Codeforces Round #609 (Div. 2)

准备掉回去div2了,每次都掉不回去,按照我之前立的flag:全部及格就变灰,现在已经及格了1科了,估计我的cf账号准备不保了。

这么菜还是把div2的AB也写了吧,上次div2only就是卡B,真的演,快把自己演到爆零了。(好像有人专门看div2的AB的题解是咋回事)

A - Equation

题意:给一个n<=1e7,找两个合数a和b使得a-b的差为n。

题解:???这啥东西,真就送分?
构造a=3n,b=2n,必含有公因子n,只有当n是1的时候是特例。

void test_case() {
    int n;
    scanf("%d", &n);
    if(n == 1) {
        puts("9 8");
        return;
    }
    printf("%d %d\n", 3 * n, 2 * n);
}

B - Modulo Equality

题意:给一个序列a,一个序列b,把这两个序列任意排序,然后使得对应位置的差在模意义下相等。

题解:数据量比较小,全部排序然后枚举错开的位置就可以。好像有个比较新手的粉丝,正好让他去学一下模意义的四则运算。

int a[2005], b[4005];

void test_case() {
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    sort(a + 1, a + 1 + n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &b[i]);
    sort(b + 1, b + 1 + n);
    for(int i = 1; i <= n; ++i)
        b[i + n] = b[i];
    int ans = INF;
    for(int d = 0; d < n; ++d) {
        int dif = (b[1 + d] - a[1] + m) % m;
        for(int i = 1; i <= n; ++i) {
            if((b[i + d] - a[i] + m) % m != dif) {
                dif = INF;
                break;
            }
        }
        ans = min(ans, dif);
    }
    printf("%d\n", ans);
}

他好像说要去找很多其他人的博客才能看懂,太有毅力了,想起我大一的时候都是看一下不会就关掉的。

那正好告诉他详细的思路:

假如不是模运算下的减法,就直接排序之后对应位置作差,然后看差是不是都相等。
但是这里是模意义下的减法,存在小数字应该和大数字对应的情况,但是由于ai和bi的取值范围是[0,m),这种情况只能出现一次,那么把b[i+n]复制一遍就可以。

意思就是bi本身比如是:

0 0 1 2 3 3 4 

这里是模5意义下,那么这里bi复制一遍,相当于:

0 0 1 2 3 3 4 | 0 0 1 2 3 3 4
0 0 1 2 3 3 4 | 5 5 6 7 8 8 9

C - Long Beautiful Integer

题意:给一个n位10进制数字串s(首位不为0),构造一个数字串t(首位不为0),使得t串是有周期k,且t串>=s串,且t串最小。

题解:想了一大堆乱七八糟的做法,最后其实很简单。把数字s的前k位复制若干次直到长度为n,然后和s比较,假如比s小就给这个数字s的前k位代表的数字+1,然后再复制若干次,这次一定更大。

这个构造是最小的,因为要比s大,所以前k位都是至少要和s相同,然后受限于周期性后面只能够不断重复。假如最后弄出来的不够大那么在前面的数字位+1之后就已经从第k位开始严格比s大了。小心连续进位的情况:

6 3
299387

但是不可能会进位得到比n位还长的数字,因为没有串可以比999..9更大。

吸取教训以后要写直接测试多组的程序,毕竟我的电脑编译运行是真的慢。

6 2
163456
7 2
1934569
7 2
1917165
int n, k;
char s[200005];
char t[200005];
void test_case() {
    scanf("%d%d%s", &n, &k, s + 1);
    for(int i = 1; i <= k; ++i) {
        t[i] = s[i];
        for(int j = i; j <= n; j += k)
            t[j] = t[i];
    }
    bool suc = 1;
    for(int i = 1; i <= n; ++i) {
        if(t[i] < s[i])
            suc = 0;
        else if(t[i] > s[i])
            break;
    }
    if(suc) {
        printf("%d\n", n);
        puts(t + 1);
        return;
    }
    for(int i = k; i >= 1; --i) {
        ++t[i];
        if(t[i] <= '9') {
            for(int j = i; j <= n; j += k) 
                t[j] = t[i];
            break;
        } else {
            t[i] = '0';
            for(int j = i; j <= n; j += k) 
                t[j] = t[i];
        }
    }
    printf("%d\n", n);
    puts(t + 1);
}

猜你喜欢

转载自www.cnblogs.com/KisekiPurin2019/p/12078782.html