Codeforces Round #659 (Div. 2)【ABCD】(題解)
阿新 • • 發佈:2020-07-26
涵蓋知識點:思維、博弈
比賽連結:傳送門
A - Common Prefixes
題意: 構造\(n+1\)個字串使得第\(i\)個和第\(i+1\)個字串的最長公共字首的長度為\(a_i\)
題解: 一開始全a,後面隨便改一改。
Accept Code:
#include <bits/stdc++.h> using namespace std; const int maxn=110; int a[maxn]; int main(){ int t;cin>>t; while(t--){ int n;cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; string s(55,'a'); cout<<s<<"\n"; for(int i=1;i<=n;i++){ s[a[i]]++; if(s[a[i]]=='z'+1)s[a[i]]='a'; cout<<s<<"\n"; } } return 0; }
B2 - Koa and the Beach (Hard Version)
題意: 共有\(n\)片海域,初始深度分別給定。潮汐會以\(2k\)為週期上下波動影響深度,前\(k\)秒以\(1m/s\)的速度加深,後\(k\)秒以\(1m/s\)速度變淺。每一秒都可以選擇呆在當前海域或前往下一海域,但是當深度大於\(l\)時就會淹死。問能否到達最後的終點。
題解: 確定所有深度加\(k\)小於等於\(l\)的點為安全區,可以在任意的安全區停留任意長的時間。然後儘可能選擇最早的不會淹死的時間進入下一節點。
Accept Code:
#include <bits/stdc++.h> using namespace std; const int maxn=3e5+10; int d[maxn]; int main(){ int t;cin>>t; while(t--){ int n,k,l; cin>>n>>k>>l; vector<int> safe={0}; for(int i=1;i<=n;i++){ cin>>d[i]; if(d[i]+k<=l)safe.push_back(i); } safe.push_back(n+1); bool flag=true; for(int i=1;i<safe.size()&&flag;i++){ int tide=k,down=-1; for(int j=safe[i-1]+1;j<safe[i];j++){ tide+=down; if(down==-1)tide-=max(0,d[j]+tide-l); if(tide<0||d[j]+tide>l){flag=false;break;} if(tide==0)down=1; } } puts(flag?"Yes":"No"); } return 0 ; }
C - String Transformation 1
題意: 給定兩個字串,每次可以選擇一個字母然後把\(a\)中所有的那個字母變為比他大的另一個字母,問最少幾次能把\(a\)變為\(b\)。
題解: 貪心,直接按照需求從小到大模擬一遍。
Accept Code:
#include <bits/stdc++.h> using namespace std; const int maxn=20; int c[maxn][maxn]; int main(){ int t;cin>>t; while(t--){ int n;cin>>n; string a,b; cin>>a>>b; memset(c,0,sizeof c); int ans=0; for(int i=0;i<n;i++){ if(a[i]>b[i]){ puts("-1"); goto st; } c[a[i]-'a'][b[i]-'a']++; } for(int i=0;i<19;i++){ int tmp=21; for(int j=i+1;j<20;j++){ if(c[i][j])tmp=min(tmp,j); } if(tmp!=21){ ans++; for(int j=i+1;j<20;j++){ c[tmp][j]+=c[i][j]; } } } cout<<ans<<"\n"; st:; } return 0; }
D - GameGame
題意: 博弈,兩人拿數,異或值大的勝。
題解: 若所有值的異或值\(sum\)為\(0\)則平局。否則只要判斷\(sum\)的最高位。問題轉化為誰拿走了奇數個最高位的數字就獲勝。如果數字的個數為偶數個,那麼最後一次拿的人是後手,顯然先手必勝,只要先取一個符合要求的接下來模仿對手即可。接下來考慮數字個數為奇數的情況,若含最高位的數字個數對\(4\)取模結果為\(1\),那麼先手可以先取一個含最高位的數字,接下來模仿對手的操作。否則先後手交換。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],cnt[2];
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
int sum=0;
for(int i=0;i<n;i++){
cin>>a[i];
sum^=a[i];
}
if(sum==0){
puts("DRAW");
continue;
}
int b=1<<(31-__builtin_clz(sum));
memset(cnt,0,sizeof cnt);
for(int i=0;i<n;i++)cnt[bool(a[i]&b)]++;
if(cnt[1]%4==1||n%2==0)puts("WIN");
else puts("LOSE");
}
return 0;
}