• CodeForces 820C


    题意略。

    这道题目的出题者竟然被hack了!?

    我的思路是:在游戏开始时,为了尽量少地用字母,我应该尽量选取计算机输出的前a个字母中已经使用过的字母。但是为了使电脑也尽量少用字母,我添加的这b个字母应该是一样的,

    这样我才能给电脑留出更多的使用已经出现过的字母的空间。

    假设现在计算机已经走完了它的一步,现在轮到我了,现在字符串总长度为i。

    当a > b时,我添加字母的范围是[i - (a - b) + 1,i]这(a - b)个字母(连续添加b个一样的),这样可以发现出现了长度为2 * (a + b)的循环节,我们把这(a - b)种循环节构造出来,储存在数组中。

    当a > b时,我只用添加b个str[i]这个字符就行了。这样它的循环节也是2 * (a + b)的。

    详见代码:

    #include<bits/stdc++.h>
    #define maxn 100
    using namespace std;
    
    char str[30][maxn];
    int visit[maxn];
    int len,tot,kind,a,b,l,r;
    
    void prepare(){
        tot = (a <= b ? a + 1 : 2 * a - b);
        len = ((a + b)<<1);
        if(b >= a){
            kind = 1;
            for(int i = 1;i <= a;++i) str[1][i] = 'a' + i - 1;
            for(int i = a + 1;i <= a + b;++i) str[1][i] = str[1][a];
            for(int i = a + b;i > b;--i) visit[str[1][i] - 'a'] = 1;
            for(int i = a + b + 1,j = 0;i <= 2 * a + b;++i){
                while(visit[j]) ++j;
                str[1][i] = 'a' + j;
                visit[j] = 1;
            }
            for(int i = a + b + a + 1;i <= a + b + a + b;++i)
               str[1][i] = str[1][a + b + a];
            for(int i = 2 * (a + b) + 1;i <= 4 * (a + b);++i)
                str[1][i] = str[1][i - 2 * (a + b)];
            str[1][4 * (a + b) + 1] = '';
           }
           else{
               kind = a - b;
               for(int k = 1;k <= a - b;++k){
                   memset(visit,0,sizeof(visit));
                   for(int i = 1;i <= a;++i) str[k][i] = 'a' + i - 1;
                for(int i = a + 1;i <= a + b;++i) str[k][i] = str[k][k + b];
                for(int i = a + b;i > b;--i) visit[str[k][i] - 'a'] = 1;
                for(int i = a + b + 1,j = 0;i <= 2 * a + b;++i){
                    while(visit[j]) ++j;
                    str[k][i] = 'a' + j;
                    visit[j] = 1;
                }
                for(int i = a + b + a + 1;i <= a + b + a + b;++i)
                    str[k][i] = str[k][a + b + a];
                for(int i = 2 * (a + b) + 1;i <= 4 * (a + b);++i)
                    str[k][i] = str[k][i - 2 * (a + b)];
                str[k][4 * (a + b) + 1] = '';
            }
        }
    }
    
    int main(){
        scanf("%d%d%d%d",&a,&b,&l,&r);
        prepare();
        if(r - l >= len) printf("%d
    ",tot);
        else{
            r = (r - 1) % len + 1;
            l = (l - 1) % len + 1;
            if(r < l) r += len;
            int ans = maxn;
            memset(visit,0,sizeof(visit));
            for(int k = 1;k <= kind;++k){
                int temp = 0;
                memset(visit,0,sizeof(visit));
                for(int i = l;i <= r;++i){
                    if(visit[str[k][i] - 'a'] == 0){
                        ++temp;
                        visit[str[k][i] - 'a'] = 1;
                    }
                }
                ans = min(temp,ans);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    A*算法实现 八数码问题
    poj 1077 Eight(bfs,dbfs, A*)
    poj 1729 Jack and Jill (搜索,bfs)
    poj 4105 拯救公主(bfs)
    poj4091The Closest M Points(KD-tree)
    资源整理
    推荐 VS2010入门教程—鸡啄米
    Cstring的使用
    VC 中TEXT、_T、L的区别
    电脑内存和CPU的关系
  • 原文地址:https://www.cnblogs.com/tiberius/p/8472529.html
Copyright © 2020-2023  润新知