zoukankan      html  css  js  c++  java
  • Codeforces Round #726 (Div. 2) 题解

    本场链接:Codeforces Round #726 (Div. 2)

    A. Arithmetic Array

    按题意模拟即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            int n,sum = 0;scanf("%d",&n);
            forn(i,1,n)
            {
                int x;scanf("%d",&x);
                sum += x;
            }
            if(sum == n)    puts("0");
            else if(sum < n)    puts("1");
            else printf("%d
    ",sum - n);
        }
        return 0;
    }
    
    

    B. Bad Boy

    不难猜想到四个角是不会变得更差的选择。枚举所有选择的情况即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    #define x first
    #define y second
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            ll n,m,a,b;scanf("%lld%lld%lld%lld",&n,&m,&a,&b);
            pii qua[4] = {{1,1},{1,m},{n,1},{n,m}},op[2] = {{1,1},{1,1}};
            ll res = 0;
            forn(i,0,3) forn(j,0,3)
            {
                int x1 = qua[i].x,y1 = qua[i].y,x2 = qua[j].x,y2 = qua[j].y;
                ll dist = abs(a - x1) + abs(b - y1) + abs(x2 - x1) + abs(y2 - y1) + abs(a - x2) + abs(b - y2);
                if(dist > res)
                {
                    res = dist;
                    op[0] = qua[i];
                    op[1] = qua[j];
                }
            }
            printf("%d %d %d %d
    ",op[0].x,op[0].y,op[1].x,op[1].y);
        }
        return 0;
    }
    
    

    C. Challenging Cliffs

    由于(|h_1-h_n|)最小是前提条件,所以优先满足。不妨对整个数组排序,那么可以快速找到:左边最小且之差最小的一对数。之后分配不难想到要使从第一个元素就开始得到贡献,应该从小到大依次填入没填的数,且第一个数比最左侧的大,剩下的继续按大小分配即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    const int N = 2e5+7;
    int a[N],ans[N];
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            int n;scanf("%d",&n);
            forn(i,1,n) scanf("%d",&a[i]);
            sort(a + 1,a + n + 1);
            int p = 1,cur = 2e9+100;
            forn(i,1,n - 1)
            {
                if(abs(a[i] - a[i + 1]) < cur)
                {
                    p = i;
                    cur = abs(a[i] - a[i + 1]);
                }
            }        
            int idx = 2;
            ans[1] = a[p];ans[n] = a[p + 1];
            forn(i,p + 2,n) ans[idx++] = a[i];
            forn(i,1,p - 1) ans[idx++] = a[i];
            forn(i,1,n) printf("%d ",ans[i]);
            puts("");
        }
    
        return 0;
    }
    
    

    D. Deleting Divisors

    • (n)是奇数,则删除一个因子一定会让(n)变成一个偶数(且不是(2^k))。
    • (n)是偶数但不是(2^k)则可以通过减去一个奇因子的办法使之变成一个奇数。如果先手(n)是偶数那么一定能让后手始终是一个奇数,最后要么走到(1)要么走到质数,显然两者都是必败态。所以(n)是偶数且不是(2^k)时先手必胜,奇数时必败。
    • (n)(2^k),若把(n)变成一个偶数但不是(2^k)显然必败,所以只能继续让他是一个(2^k),由于(2^k-2^{k-1}=2^{k-1}).所以当(k)是奇数时先手必败,反之先手必胜。
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            int n;scanf("%d",&n);
            if(n % 2)
            {
                puts("Bob");
                continue;
            }
            int cnt = 0;
            while(n % 2 == 0)
            {
                ++cnt;
                n /= 2;
            }
            if(n > 1 || cnt % 2 == 0)   puts("Alice");
            else puts("Bob");
        }
        return 0;
    }
    
    

    E1. Erase and Extend (Easy Version)

    不难想到答案一定是某个前缀重复若干次得到的,暴力枚举即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    
    int main()
    {
        Angel_Dust;
        int n,k;cin >> n >> k;
        string cur,s;cin >> s;
        string res;
        forn(i,0,n - 1)
        {
            cur += s[i];
            string nxt;
            forn(j,1,(k + i) / (i + 1))   nxt += cur;
            nxt.resize(k);
            if(res == "" || nxt < res)  res = nxt;
        }
        cout << res << endl;
        return 0;
    }
    
    

    E2. Erase and Extend (Hard Version)

    copy来的牛逼做法:记(prefix(x))表示前缀([1,x])(f_k(s))表示将(s)重复若干次直到其长度(geq k)得到的串。

    问题等价于求一个(x)使(f_k(prefix(x)))最小。

    考虑枚举(xin[2,n])即当前答案(pos=1),每次尝试更新(pos):若(f_k(prefix(pos))[x] > s[x])则换上(x)进入序列会更优,反之则不会变得更好,因为以后的所有前缀一定包含(s[x]),直接退出即可。如果相同则说明当前这一位无所谓,答案可能在后面继续做即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    const int N = 5e5+7;
    char s[N];
    
    int main()
    {
        int n,m;scanf("%d%d%s",&n,&m,s + 1);
        int k = min(n,m),pos = 1;
        forn(i,2,k)
        {
            if(s[i] < s[(i - 1) % pos + 1])   pos = i;
            else if(s[i] > s[(i - 1) % pos + 1])  break;
        }
        forn(i,1,m) printf("%c",s[(i - 1) % pos + 1]);
        return 0;	
    }
    
    

    F. Figure Fixing

    首先考虑无解:若(sum v_i)(sum t_i)奇偶性不同,则一定无解。

    如果(m=n-1)则是一个树,因为树一定是一个二分图,那么边上的操作等价于对两个集合同时加或减一个值,相当于白干。对树二染色若两个集合的(sum v_i - t_i)值不同则无解,反之一定有解。如果不是二分图,则一定有两个点染色的时候会是同色的:这两个点可以随意调整集合的和,所以一定有解。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    const int N = 2e5+7,M = 2 * N;
    int edge[M],succ[M],ver[N],idx;
    int v[N],t[N],col[N];
    ll sum[2];
    
    void add(int u,int v)
    {
        edge[idx] = v;
        succ[idx] = ver[u];
        ver[u] = idx++;
    }
    
    bool dfs(int u,int c,int d)
    {
        col[u] = c;
        sum[d] += v[u] - t[u];
        for(int i = ver[u];~i;i = succ[i])
        {
            int v = edge[i];
            if(!col[v])
            {
                if(!dfs(v,3 - c,d ^ 1)) return 0;
            }
            else if(col[v] == c)    return 0;
        }
        return 1;
    }
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            int n,m;scanf("%d%d",&n,&m);
            forn(i,1,n) ver[i] = -1,col[i] = 0;idx = 0;
            sum[0] = 0;sum[1] = 0;
            forn(i,1,n) scanf("%d",&v[i]);
            forn(i,1,n) scanf("%d",&t[i]);
            forn(i,1,m)
            {
                int u,v;scanf("%d%d",&u,&v);
                add(u,v);add(v,u);
            }
            ll vsum = 0,tsum = 0;
            forn(i,1,n) vsum += v[i],tsum += t[i];
            if(abs(vsum) % 2 != abs(tsum) % 2)    puts("NO");
            else
            {
                if(!dfs(1,1,0) || sum[1] == sum[0]) puts("YES");
                else puts("NO");
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    POJ 1015 Jury Compromise【DP】
    POJ 1661 Help Jimmy【DP】
    HDU 1074 Doing Homework【状态压缩DP】
    HDU 1024 Max Sum Plus Plus【DP,最大m子段和】
    占坑补题。。最近占的坑有点多。。。
    Codeforces 659F Polycarp and Hay【BFS】
    Codeforces 659E New Reform【DFS】
    Codeforces 659D Bicycle Race【计算几何】
    廖大python实战项目第四天
    廖大python实战项目第三天
  • 原文地址:https://www.cnblogs.com/HotPants/p/14925945.html
Copyright © 2011-2022 走看看