【codeforces】【比賽題解】#869 CF Round #439 (Div.2)
良心賽,雖然我遲了半小時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)