标签:尘埃 can blog scan 不同 越界 就会 题意 答案
良心赛,虽然我迟了半小时233333。
比赛链接:#869。
呃,CF的比赛都是有背景的……上次是《哈利波特》,这次是《物语》……
【A】巧妙的替换
题意:
Karen发现了石头剪刀布的决定性规律,看透了这个游戏的本质,使得石头剪刀布再无奥秘可言。
但是他的哥哥,Koyomi发明了一个新游戏:
他们先选定一个数\(n\),然后选出\(2n\)个互不相同的数,为\(x_{1},x_{2},\cdots,x_{n}\)和\(y_{1},y_{2},\cdots,y_{n}\)。
接下来他们数出无序数对\((i,j)\)的数量,使得\((i,j)\)满足\(x_{a}\hat{\;}y_{b}\)等于这\(2n\)个数中的某一个。
其中\(\hat{\;}\)符号代表按位异或。
如果这种数对的数量是偶数,则Karen赢,否则Koyomi赢。
判断谁会赢。
输入:
第一行一个数\(n,(1\leqslant n\leqslant2000)\)。
接下来一行n个数,表示\(x_{1},x_{2},\cdots,\x_{n}(1\leq x_{i}\leq2\cdot10^6)\)。
接下来一行n个数,表示\(y_{1},y_{2},\cdots,\y_{n}(1\leq y_{i}\leq2\cdot10^6)\)。
输出:
一行一个字符串"Karen"或"Koyomi",表示谁会赢,注意大小写。
题解:
把\(2n\)个数有没有出现过记下来,然后\(O(n^2)\)乱搞。
唯一的坑点是如\(2000000\hat{\;}97151=2097151\),大于2000000,所以数组要防止越界。
#include<cstdio> int n,a[10001],y[10001],ans; bool vis[2100001]; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",a+i), vis[a[i]]=1; for(int i=1;i<=n;++i) scanf("%d",y+i), vis[y[i]]=1; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(vis[a[i]^y[j]]) ++ans; if(ans&1) puts("Koyomi"); else puts("Karen"); }
【B】不朽的神话
题意:
堆积药草和焚香,而后从其先祖的尘埃中重生,“凤凰涅槃”的故事被很多人所熟知。
凤凰有很长的生命周期,它每隔\(a!\)年就会轮回转世,这里\(a!\)表示\(a\)的阶乘。
Koyomi不关心这些,在他和更多的奇物搞的一团糟之前,他想知道在\(b!\)年中,凤凰会重生多少次,即\(\frac{b!}{a!}\)。
当\(a\leq b\)时,\(\frac{b!}{a!}\)总是整数。
答案可能会很大,所以Koyomi想知道答案的最后一位(十进制下)。
输入:
第一行,两个整数\(a,b(0\leq a\leq b\leq 10^{18})\)。
输出:
一个数字,表示答案的最后一位。
题解:
当\(b-a\geq5\)时,输出0。
#include<cstdio> int main(){ long long a,b; scanf("%I64d%I64d",&a,&b); if(b-a>=5) puts("0"); else{ int last=1; for(long long c=a+1;c<=b;++c) last=last*(c%10); printf("%d",last%10); } return 0; }
【C】有趣的迷恋
题意:
齐心协力,我们可以以超乎想象的速度到达任何地方!现在,Fire Sisters——Karen和Tsukihi正在前往一个她们从未到达的地方——水中的小岛!
有三种不同类型的小岛,方便地,各自涂上了红,蓝,紫三色。每种颜色的小岛各自有\(a,b,c\)个。
这些小岛之间初始时互相分离。可以在小岛之间架桥,两个小岛间最多架一座桥。
但要满足:任意两个不同的颜色相同的小岛的最短距离要大于等于3(桥的长度为1)。
请你计算出不同的架桥方案有多少种。答案对998244353取模。
输入:
三个非负整数,\(a,b,c(0\leq a,b,c\leq5000)\)。
输出:
一个数,不同的架桥方案数对998244353取模的结果。
题解:
观察到一个颜色的小岛不能连向自己颜色的,也不能向同一颜色的小岛连去两条边。
也就是说,一个小岛能向另两种颜色的小岛连边,一种颜色最多连一条。
设\(f[i][j]\)表示两种颜色的小岛各有\(a,b\)个,它们之间互相连边,并满足条件的种数。
则答案等于\(f[a][b]\cdot f[b][c]\cdot f[c][a]\)。
而\(f[i][j]=f[i-1][j]+j\cdot f[i-1][j-1]\),这一点可以简单地推出。
我们使用动态规划算法求出所有可能的\(f[i][j]\)即可。
#include<cstdio> const int Mod=998244353; long long f[5005][5005]; int main(){ for(int i=0;i<=5000;++i) f[0][i]=f[i][0]=1; for(int i=1;i<=5000;++i) for(int j=1;j<=5000;++j) f[i][j]=(f[i-1][j]+j*f[i-1][j-1])%Mod; int a,b,c; scanf("%d%d%d",&a,&b,&c); printf("%I64d",f[a][b]*f[b][c]%Mod*f[c][a]%Mod); return 0; }
【D】
不会
【E】
二维树状数组可做。
【codeforces】【比赛题解】#869 CF Round #439 (Div.2)
标签:尘埃 can blog scan 不同 越界 就会 题意 答案
原文地址:http://www.cnblogs.com/PinkRabbit/p/7653493.html