1. 程式人生 > >【codeforces】【比賽題解】#869 CF Round #439 (Div.2)

【codeforces】【比賽題解】#869 CF Round #439 (Div.2)

sister 十進制 長度 http include 越界 print const bool

良心賽,雖然我遲了半小時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)