AtcoderR 097 相邻球交换目的递增DP

A

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll LLmaxn = 2e18;
string a;
int K;
string str[10000000];
int pop = 0;
map<string, int> mp;
int main()
{
        cin >> a;
        cin >> K;
        for (int i = 0; i <= 25 && pop < K; i++)
        {
                for (int j = 0; j < a.size(); j++)
                {
                        if (a[j] == 'a' + i)
                        {
                                string now = "";
                                for (int k = j; k < min((int)a.size(), j + K); k++)
                                {
                                        now += a[k];
                                        if (!mp[now])
                                        {
                                                str[++pop] = now;
                                                //cout<<now<<endl;
                                                mp[now]++;
                                        }
                                }
                        }
                }
        }
        sort(str + 1, str + pop + 1);
        cout << str[K] << endl;
        return 0;
}
View Code

B

给1-N的一个排列 再给你M个Xi,Yi表示Xi与Yi位置的数可以无限次交换

解:

并查集 因为交换次数是无线的所以在一个集内的数字可以到其他任何一个位置

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll LLmaxn = 2e18;
const int N = 100005;
int par[N];
void init(int n)
{
        for (int i = 0; i <= n; i++)
        {
                par[i] = i;
        }
}
int find(int x)
{
        return par[x] == x ? x : par[x] = find(par[x]);
}
void unite(int x, int y)
{
        x = find(x);
        y = find(y);
        if (x != y)
        {
                par[x] = y;
        }
}
int num[N];
int where[N];
int a, b;
int main()
{
        int n;
        int m;
        cin >> n;
        cin >> m;
        init(n);
        int anser = 0;
        for (int i = 1; i <= n; i++)
        {
                cin >> num[i];
                where[num[i]] = i;
        }
        for (int i = 1; i <= m; i++)
        {
                cin >> a >> b;
                unite(a,b);
        }
        for (int i = 1; i <= n; i++)
        {
                if (find(where[i]) == find(i))
                {
                        anser++;
                }
        }
        cout << anser << endl;
        return 0;
}
View Code

C

有2N个球 一半是白的 一半是黑的 每个白球和黑球上都有一个数字 分别都可以组成1-N

在一次操作内你可以交换相邻的两个球 问你最少需要多少次操作使得从左到右 白球和黑球都是递增序

猜你喜欢

转载自www.cnblogs.com/Aragaki/p/9031848.html