打卡 Codeforces Round #599 (Div. 2)

A题
水题,贪心即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
    char ch = getchar(); ll x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int k, n;
int a[1005];
int main()
{
    k = read();
    while (k--)
    {
        n = read();
        upd(i, 1, n)a[i] = read();
        sort(a + 1, a + 1 + n);
        int wid = 0;
        int hi = 0;
        hi = a[n]; wid = 1;
        int ans = 0;
        ans = min(hi, wid);
        dwd(i, n-1, 1)
        {
            hi = min(hi, a[i]);
            wid++;
            ans = max(ans,min(hi,wid));
        }
        printf("%d\n", ans);
    }
    return 0;
}

B题
继续暴力,有点冒泡排序的感觉。
只要每个字符的出现次数是偶数,那么一定可以通过某种交换使得两个字符串相等。暴力枚举和交换即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
    char ch = getchar(); ll x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int k, n;
string s, t;
map<char, int>mp_s,mp_t,mp;
vector<int> pos[1005], pos_s[1005];
int main()
{
    k = read();
    while (k--)
    {
        n = read();
        mp_s.clear(); mp_t.clear(); mp.clear();
        upd(i, 0, n)pos[i].clear();
        cin >> s >> t;
        if (s.size() != t.size()) { cout << "no" << endl; continue; }
        int cnt = 0;
        for (auto p : s)mp_s[p]++,mp[p]++,pos_s[p].push_back(cnt++);
        cnt = 0;
        for (auto p : t)mp_t[p]++,pos[p].push_back(cnt++),mp[p]++;
        bool flag = 0;
        for (auto p : mp)if (p.second % 2)flag = 1;
        if (flag) { printf("NO\n"); continue; }
        vector<pir>ans;
        up(i, 0, s.size())
        {
            if (s[i] != t[i])
            {
                bool flag = 0;
                up(j, i+1, t.size())
                {
                    if (t[j] == s[i])
                    {
                        swap(s[i + 1], t[j]);
                        swap(s[i + 1], t[i]);
                        ans.push_back(make_pair(i + 2, j+1));
                        ans.push_back(make_pair(i + 2, i+1));
                        flag = 1;
                        break;
                    }
                }
                if (!flag)
                {
                    up(j, i+1, s.size())
                    {
                        if (s[j] == s[i])
                        {
                            swap(s[j], t[i]);
                            ans.push_back(make_pair(j+1, i+1));
                            break;
                        }
                    }
                }
            }
        }
        printf("YES\n");
        printf("%d\n", ans.size());
        //cout << s << " " << t << endl;
        for (auto k : ans)printf("%d %d\n", k.first, k.second);
    }
    return 0;
}

C题
我们首先看有两个数字互质的情况。
由完全剩余系可以知道,如果a,b两个数字互质,a*1,a*2,a*3,...a*(b-1),a*b 模上b,可以取到1~b-1的一个permutation。
即,我们假设x染成颜色1,x+a,x+2a,x+3a....都将成为颜色1,由上述定理可知,(x+1)+b,(x+1)+b*2....肯定会由c,c=x+m*a,c=(x+1)+n*b,所以x和x+1一定会被染色成一个颜色。
我们对n进行唯一分解定理,如果有两个质数,那么答案为1。
如果只有一个质数,答案为该质数。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
    char ch = getchar(); ll x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
ll n;
vector<ll>vec;
int main() {
 
    n = read();
    if (n == 1)
    {
        printf("%d\n", 1);
        return 0;
    }
    for (ll i = 2; i*i <= n; i++)
    {
        while (!(n%i))
        {
            while (!(n%i))n /= i;
            vec.push_back(i);
        }   
    }
    if (n > 1)vec.push_back(n);
    if (vec.size() > 1)
    {
        printf("%d\n", 1);
    }
    else
    {
        printf("%lld\n", vec.front());
    }
    return 0;
}

D题
还是暴力。
相当于判断,通过代价为零的边,能有多少个连通块,答案为连通块的数目减一。
因为是个完全图,每一个点必然和其他所有点有边,我们把能通过0的边连在一起的点缩成一块。每一个块之间,将必然会使用代价为1的边相连,所以代价为快数-1。
考虑暴力dfs,开vis数组,保证每一个节点只会被访问一次。
每一次dfs考虑没有被vis过的,和不会权值1的边相连的点。
要注意优化,单纯来看时间复杂度是nlogn(用map来搜索了的所有有log)
但是块数如果太多,因为每一次访问都需要遍历所有n个点,将会变成n^2
故再开一个set,访问过的点从set里面删除,每一次脂肪问set里面的点。
这样复杂度就将变成,sigma size(块)*logn
(当然也可以理解成为树就是n个点,n-1条边,所以最后需要块数-1条边)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
    char ch = getchar(); ll x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
set<int>s[N],init_s;
int n, m;
int height[N];
int pr[N];
int vis[N];
void init()
{
    upd(i, 0, n)
        height[i] = 1, pr[i] = i;
    upd(i, 1, n)init_s.insert(i);
}
int find_pr(int x)
{
    return pr[x] == x ? x : pr[x] = find_pr(pr[x]);
}
void unit(int x, int y)
{
    x = find_pr(x);
    y = find_pr(y);
    if (x == y)return;
    if (height[x] < height[y])
        swap(x, y);
    height[x] += height[y];
    pr[y] = x;
}
void dfs(int u)
{
    vis[u] = 1;
    vector<int>vec;
    for (auto p : init_s)
    {
        if(s[u].find(p)==s[u].end())
            vec.push_back(p);
    }
    for (auto p : vec)init_s.erase(p);
    for(auto p:vec) {
        if (vis[p])continue;
        dfs(p);
        unit(u, p);
    }
}
int main()
{
    n = read(), m = read();
    int u, v;
    up(i, 0, m)
    {
        u = read(), v = read();
        s[u].insert(v);
        s[v].insert(u);
    }
    init();
    int ans = 0;
    upd(i, 1, n)
    {
        if (!vis[i])
        {
            init_s.erase(i);
            dfs(i);
        }
    }
    int nums = 0;
    upd(i, 1, n)
    {
        if (pr[i] == i)nums++;
    }
    printf("%d\n", nums - 1);
}

猜你喜欢

转载自www.cnblogs.com/LORDXX/p/12077819.html