CCPC2018

Gym https://codeforces.com/gym/102823


J. Stone Game


找到所有的谷
然后把整个谷往下拽
需要稍微处理一下峰
另外左右两端也需要处理一下。

实现的时候,直接开一个数组存下最终的唯一指定必败态

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>

using namespace std;

const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;

int t, n;
int A[MAXN];
int List[MAXN];
int ss[MAXN];
int ans;

int main()
{
    scanf("%d", &t);

    for (int _case = 1; _case <= t; ++_case)
    {
        ans = 0, List[0] = 0;
        printf("Case %d: ", _case);

        scanf("%d", &n);
        A[0] = A[n + 1] = INF;
        for (int i = 1; i <= n; ++i)
        {
            ss[i] = 0;
            scanf("%d", &A[i]);
        }
        for (int i = 1; i <= n; ++i)
        {
            if (A[i] < A[i-1] && A[i] < A[i+1])
            {
                List[++List[0]] = i;
            }
        }

        for (int prefA, j, i = 1; i <= List[0]; ++i)
        {
            ss[List[i]] = 0;
            j = List[i], prefA = 0;
            while (j > 1 && A[j] < A[j - 1])
            {
                --j; ++prefA;
                if (prefA > ss[j]) ss[j] = prefA;
            }
            j = List[i], prefA = 0;
            while (j < n && A[j] < A[j + 1])
            {
                ++j; ++prefA;
                if (prefA > ss[j]) ss[j] = prefA;
            }
        }

        for (int i = 1; i <= n; ++i) ans ^= (A[i] - ss[i]) & 1;
        puts(ans ? "Alice" : "Bob");
    }
    return 0;
}


D. Bits Reverse


翻转连续的三个二进制位其实也就是交换两个相隔一位的二进制位
那么实际上我们可以将一个数的二进制位分成奇数位和偶数位。
接下来剩下的问题就是,只允许交换相邻两位的情况下,最少要交换几次
这个老经典了

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
using namespace std;
#define sysp system("pause");
int t;
long long x, y;
int x_ones[2];
int y_ones[2];
int x_bits[2][100];
int y_bits[2][100];
int x_ptr, y_ptr;
int ans;
int sb;
int main()
{
    scanf("%d", &t);
    for (int cas = 1; cas <= t; ++cas)
    {
        printf("Case %d: ", cas);
        scanf("%lld%lld", &x, &y);
        x_ones[0] = x_ones[1] = y_ones[0] = y_ones[1] = ans = sb = 0;
        x_bits[0][0] = x_bits[1][0] = y_bits[0][0] = y_bits[1][0] = 0;
        while (x)
        {
            if (x & 1)
            {
                ++x_ones[sb & 1];
            }
            x_bits[sb & 1][++x_bits[sb & 1][0]] = x & 1;
            x >>= 1;
            ++sb;
        }
        sb = 0;
        while (y)
        {
            if (y & 1)
            {
                ++y_ones[sb & 1];
            }
            y_bits[sb & 1][++y_bits[sb & 1][0]] = y & 1;
            y >>= 1;
            ++sb;
        }
        if ((x_ones[0] != y_ones[0]) || (x_ones[1] != y_ones[1]))
        {
            puts("-1");
            continue;
        }
        x_ptr = y_ptr = 1;
        while (x_ptr <= x_bits[0][0] && y_ptr <= y_bits[0][0])
        {
            while (x_bits[0][x_ptr] != 1)
                ++x_ptr;
            while (y_bits[0][y_ptr] != 1)
                ++y_ptr;
            ans += abs(x_ptr - y_ptr);
            ++x_ptr;
            ++y_ptr;
        }
        x_ptr = y_ptr = 1;
        while (x_ptr <= x_bits[1][0] && y_ptr <= y_bits[1][0])
        {
            while (x_bits[1][x_ptr] != 1)
                ++x_ptr;
            while (y_bits[1][y_ptr] != 1)
                ++y_ptr;
            ans += abs(x_ptr - y_ptr);
            ++x_ptr;
            ++y_ptr;
        }
        printf("%d
", ans);
    }
    // sysp
    return 0;
}


G. Greatest Common Divisor


比较有意思
差值这个,懂GCD的都应该懂
然后我直接把差值GCD求出来就拿去用了
实际上应该得对它的每个质因子都做一次。
所以可以先跑一次素数筛,但是我有点懒,这个没必要
除此之外特判巨多
还是多组数据的,非常精神污染
Wrong answer on test 1

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
using namespace std;
#define sysp system("pause");
const int MAXN = 1e5 + 10;
int t, n;
int a[MAXN];
long long ans;
long long g, sqg;
bool brk;
int gcd(int a, int b)
{
    return !b ? a : gcd(b, a % b);
}
int main()
{
    scanf("%d", &t);
    for (int _case = 1; _case <= t; ++_case)    
    {
        printf("Case %d: ", _case);
        scanf("%d", &n);
        g = 0;
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        sort(a + 1, a + 1 + n);
        n = unique(a + 1, a + 1 + n) - a - 1;
        for (int i = 1; i <= n; ++i)
        {
            if (i < 3)
            {
                if (i == 1) continue;
                g = a[i] - a[i - 1];
                continue;
            }
            g = gcd(g, a[i] - a[i - 1]);
        }
        if (n == 1)
        {
            puts(a[1] == 1 ? "1" : "0");
            continue;
        }
        if (g == 1)
        {
            puts("-1");
            continue;
        }
        if (a[1] % g == 0)
        {
            puts("0");
            continue;
        }
        sqg = sqrt(g);
        if (a[1] % g == 0) 
        {
            puts("0");
            continue;
        }
        ans = 1ll * (a[1] / g + 1) * g - a[1];
        brk = 0;
        for (int j, i = 2; i <= sqg; ++i)
        {
            if (g % i == 0) 
            {
                j = g / i;
                brk = (a[1] % i == 0) || (a[1] % j == 0);   
                if (brk)
                    break;
                ans = min(ans, 1ll * (a[1] / i + 1) * i - a[1]);
                ans = min(ans, 1ll * (a[1] / j + 1) * j - a[1]);
            }
        }
        if (brk)
        {
            puts("0");
            continue;
        }
        printf("%lld
", ans);
    }
    //
    // sysp
    return 0;
}


H. Hamming Distance


单独开了



L. Two Ants


样例直接懂完了
貌似又要分类讨论,我就不继续写了

原文地址:https://www.cnblogs.com/ccryolitecc/p/14020977.html