Codeforces Round #607 (Div. 2)

佐手、 提交于 2019-12-15 20:27:09

A - Suffix Three

题意:规定三种语言的结尾符,给出字符串,判断是什么语言。

void test_case() {
    string s;
    cin >> s;
    reverse(s.begin(), s.end());
    if(s.substr(0, 2) == "op")
        puts("FILIPINO");
    else if(s.substr(0, 2) == "us")
        puts("JAPANESE");
    else
        puts("KOREAN");
}

B - Azamon Web Services

题意:交换s串的最多一对字母,问是否可以严格小于c串。

题解:找最小的那个换上来,假如有多个最小的找最后面的那个。

void test_case() {
    string s, c;
    cin >> s >> c;
    int l = s.length();
    for(int i = 0; i < l; ++i) {
        int minj = i + 1;
        for(int j = i + 2; j < l; ++j) {
            if(s[j] <= s[minj])
                minj = j;
        }
        if(s[minj] < s[i]) {
            swap(s[minj], s[i]);
            break;
        }
    }
    if(s < c)
        cout << s << endl;
    else
        cout << "---" << endl;
}

C - Cut and Paste

题意:光标最开始在最左侧,每次操作:

1、向右移动光标1格
2、把光标右侧的剪切
3、粘贴光标左侧第一个数字的次数

求当光标移动到x<=1e6位置时的字符串的总长度。

题解:直接模拟,超过x的字符串就不需要操作了,直接截断,但是长度继续参与运算。比赛的时候提交的那个截断长度不是x而是固定的MAXLEN=1e6,这样在超多组数据下复杂度好像不太对的,构造几个全都是3的串就复制到GG。

const ll LMOD = 1e16;

int MAXLEN;
char s[1000005];

int l;
ll tl;

void append(int x) {
    if(s[x] == '1')
        return;
    if(s[x] == '2') {
        if(l < MAXLEN) {
            int dl = l - x, ce = min(MAXLEN, l + dl);
            for(int i = x + 1; i + dl <= ce; ++i)
                s[i + dl] = s[i];
            l += dl;
            if(l >= MAXLEN)
                l = MAXLEN;
        }
        tl += tl - x;
        if(tl >= LMOD || tl <= -LMOD)
            tl %= MOD;
        return;
    }
    if(s[x] == '3') {
        if(l < MAXLEN) {
            int dl1 = l - x, dl2 = dl1 + dl1, ce1 = min(MAXLEN, l + dl1), ce2 = min(MAXLEN, l + dl2);
            for(int i = x + 1; i + dl1 <= ce1; ++i)
                s[i + dl1] = s[i];
            for(int i = x + 1; i + dl2 <= ce2; ++i)
                s[i + dl2] = s[i];
            l += dl2;
            if(l >= MAXLEN)
                l = MAXLEN;
        }
        tl += tl - x + tl - x;
        if(tl >= LMOD || tl <= -LMOD)
            tl %= MOD;
        return;
    }
}

void test_case() {
    int c = 0;
    scanf("%d%s", &MAXLEN, s + 1);
    tl = l = strlen(s + 1);
    while(1) {
        ++c;
        append(c);
        if(c == MAXLEN)
            break;
    }
    tl = (tl % MOD + MOD) % MOD;
    printf("%lld\n", tl);
}

D - Beingawesomeism

题意:给一个黑白棋盘格,每次可以选择一个1*x或者x*1形状的矩形向一个方向移动,把经过的位置都涂成你选的那个矩形的样子,求最小的步数把整个棋盘都涂成黑色。

题解:

0、全部都是黑色
1、有边上的一行或者一列全部都是黑色,移动这个矩形就可以
2、可以构造出边上的一行或者一列全部都是黑色的,也就是角上的黑色或者中间的一行或者一列全部都是黑色
3、可以构造出角上的黑色或者中间的一行或者一列全部都是黑色的,也就是边上的黑色,注意要造出中间一行或者一列也必须是边上的黑色
4、可以构造出边上的黑色的

int r, c;
char g[205][205];
int cntr[205], cntc[205];

void test_case() {
    scanf("%d%d", &r, &c);
    for(int i = 1; i <= r; ++i)
        scanf("%s", g[i] + 1);
    for(int i = 1; i <= r; ++i)
        cntr[i] = 0;
    for(int j = 1; j <= c; ++j)
        cntc[j] = 0;
    int sum = 0;
    for(int i = 1; i <= r; ++i) {
        for(int j = 1; j <= c; ++j) {
            cntr[i] += g[i][j] == 'A';
            cntc[j] += g[i][j] == 'A';
            sum += g[i][j] == 'A';
        }
    }
    /* -1 */
    if(sum == 0) {
        puts("MORTAL");
        return;
    }
    /* 0 */
    if(sum == r * c) {
        puts("0");
        return;
    }
    /* 1 */
    if(cntr[1] == c || cntr[r] == c || cntc[1] == r || cntc[c] == r) {
        puts("1");
        return;
    }
    /* 2 */
    if(g[1][1] == 'A' || g[1][c] == 'A' || g[r][1] == 'A' || g[r][c] == 'A') {
        puts("2");
        return;
    }
    for(int i = 1; i <= r; ++i) {
        if(cntr[i] == c) {
            puts("2");
            return;
        }
    }
    for(int j = 1; j <= c; ++j) {
        if(cntc[j] == r) {
            puts("2");
            return;
        }
    }
    /* 3 */
    if(cntr[1] || cntr[r] || cntc[1] || cntc[c]) {
        puts("3");
        return;
    }
    /* 4 */
    puts("4");
    return;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!