Educational Codeforces Round 68 (Rated for Div. 2) A B C D

题目链接:http://codeforces.com/contest/1194


Problem A

找规律,发现会一次去掉1,3,5,7直到剩余数字小于等于一半

于是奇数剩余:2,4,6,...n-1

        偶数剩余:2,4,6,....n

问你第几个数,只要*2就行了

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;i

Problem B

送命题,复杂度摸不透,比赛时候觉得暴力的话空间开不起,时间不够跑。

一行行遍历时用vector储存下所有最长的行上面的空白格的位置(因为可能不止一条最长的),这写空白的位置是为了等会选取

最长竖时是否存在可以共同填掉一格,当然也要记下‘*’最多的那一(几)行的‘*’数目

遍历的时候同时统计每一列的‘*’数目cnt[]。

当遍历完整个图的时候,我们把vector里面的空白格全部倒出来开一个bool数组标记每个空白格的位置

开始遍历cnt也就是每一列的‘*’数目,来求答案,如果当前列的空白格被标记过,说明如果我们要填充这一列,这个空白格可以

同时受用这一列和最长的一行,所以总共需要涂色的等于最大行和这一列所欠缺的。取最大值即可。。。。。。

等等,为什么这种复杂度都能过啊喂???!

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;ibr;
int cnt[N];
bool kong[N];

int main()
{
    int T;scanf("%d",&T);while (T--){
        br.clear();
        memset(cnt,0,sizeof cnt);
        int n,m;
        int sum=-1,maxlen=-1,maxrow=-1;
        char c;
        scanf("%d %d",&n,&m);
        getchar();
        for1(i,1,n){
            sum = 0;
            vectortemp;
            for1(j,1,m){
                scanf("%c",&c);
                if (c=='.') temp.pb(j);
                else cnt[j]++,sum++;
            }
            getchar();
            if (sum>maxlen) br.clear(),br=temp,maxlen = sum;
            else if (sum==maxlen) br.insert(br.end(),temp.begin(),temp.end());
        }

//for (auto now:br) cout << now << " "; puts("");

        memset(kong,false,sizeof kong);

        for (auto now:br) kong[now] = true;

//for1(i,1,m)printf("%s",kong[i]?"kong ":"man ");puts("");

        int ans = n+m+1;

        for1(i,1,m){
            if (cnt[i]>=maxrow){
                if (kong[i]) ans = min(ans,n-cnt[i]+(m-maxlen)-1);
                else ans = min(ans,n-cnt[i]+(m-maxlen));
                maxrow = cnt[i];
            }
        }

        printf("%d\n",ans);

    }

    return 0;
}

Problem C

把第三个串拥有的字符统计出来相当于第一个串的后备隐藏能源,来和第二个串匹配,优先用串1自己的匹配串2,

最后成功的条件是串1用完,串2用完,否则不成功。

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;i0) cnt[idx(t[i])]--;
            else break;
        }

        if (tot==lens && i>=lent) printf("Yes\n");
        else puts("No");

    }
    return 0;
}

Problem D

问题转换为:n个石头,每次可取1,2,k个,先取完就赢。

这道题只有一堆,跟sg函数看起来扯不到关系。

询问有很多次,每次k都不同,那么应该有什么共同的规律。

打个表找找规律。

k不是3的倍数时:

B AAB AAB AAB...

是三3倍数时:

k=3,B AAAB AAAB AAAB...

k=6,B AAB AAAB AAB AAAB ...

k=9,B AAB AAB AAAB AAB AAB AAAB...

k=12,B AAB AAB AAB AAAB AAB AAB AAB AAAB...

......

打表:(不是AC代码,那个在下面)

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;i=k && zt[i-k]=='N')) zt[i] = 'P';
            else zt[i] = 'N';

        printf("当k=%d时:\n",k);

        for0(i,0,n+1) printf("n = %d, %s\n",i,zt[i]=='P'?"Alice,first win":"Bob,second win");

    }
    return 0;
}

代码:

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;i

总结:

①AC了几千个人的题目一定没那么难,一定要想清楚,敢暴力

ps:vector可以直接容器间赋值,vector(v.begin,vv.begin,vv.end)可以直接实现对应位置的插入

②博弈论该去系统学一学了,sg,打表,各种变形。

③分已经真的没有掉的余地了,下一场让我多A几道,求你了

你可能感兴趣的:(Codeforces补题)