Codeforces Round #650 (Div. 3) 題解
阿新 • • 發佈:2020-09-02
Problem A
我真是個傻逼,本來想判一下和前一項是否相等的,但是t3明顯就不對,後面發現就是一個模擬題,直接甲加一輸出就好了。
Problem B
首先,和下標奇偶性一樣的顯然不需要動,那麼就是看不相等的數目,因為一次交換可以使得兩個不相等的恢復,如果這個兩種數量不一樣,那麼輸出-1.
Problem C
他給你的一定是合法的,或者是特殊情況,對於一個合法的串,我們考慮因為在已有的1的範圍內不能有顧客,我們打上標記,然後再去從頭坐人,每做一個人就讓下標+k繼續判斷就好了。
Problem D
首先,0一定是字典序最大的那個字母,那麼我們肯定是要統計字串裡面字母出現的次數,然後我們統計字典序最大的字母出現的次數是否大於0的個數,大於的話,就把這個位置的答案串修改成這個字元,同時重構這個數量,不停做上述操作就好了。
程式碼實現
#include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<map> #include<iostream> #include<set> #include<cstring> #include<cmath> using namespace std; #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i) #define per(i,n,a) for (int i=n;i>=a;i--) #define MT(x,i) memset(x,i,sizeof(x) ) #define rev(i,start,end) for (int i=start;i<end;i++) #define inf 0x3f3f3f3f #define mp(x,y) make_pair(x,y) #define lowbit(x) (x&-x) #define MOD 1000000007 #define exp 1e-8 #define N 1000005 #define fi first #define se second #define pb push_back typedef long long ll; const ll INF=0x3f3f3f3f3f3f3f3f; typedef vector <int> VI; typedef pair<int ,int> PII; typedef pair<int ,PII> PIII; ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; } inline int read() { char ch=getchar(); int x=0, f=1; while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while('0'<=ch&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } int t,n,m,b[60],val[27]; string s; int vis[60]; char ans[60]; int main () { int t; scanf ("%d",&t); while (t--) { MT (vis,0),MT (ans,'0'),MT (val,0); int m; cin>>s; scanf ("%d",&m); rep (i,1,m) scanf ("%d",&b[i]); rev (i,0,s.size ()) val[s[i]-'a'+1]++; int num=0,zero=0,k=27; while (num!=m) { zero=0; rep (i,1,m) if (b[i]==0&&vis[i]==0) zero++; for (int i=k-1;i>0;i--) if (val[i]>=zero) { k=i; break; } rep (i,1,m) if (vis[i]==0&&b[i]==0) { vis[i]++,num++; ans[i]=k+'a'-1; } rep (i,1,m) if (b[i]==0&&ans[i]==k+'a'-1) { rep (j,1,m) if (b[j]) b[j]-=abs (j-i); } } rep (i,1,m) printf ("%c",ans[i]); printf ("\n"); } return 0; }
Problem E
這道題是這樣,首先肯定有迴圈節,但是他說轉k次可以,那麼迴圈節的長度不一定是k,也可能是k的因子,那麼我們去列舉k的因子,接著在數量的限制下,列舉迴圈節的數量,然後統計字串裡面的字母數,判斷下能否組成長度為列舉的因子的迴圈節,取最大值就好了。
程式碼實現
#include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<map> #include<iostream> #include<set> #include<cstring> #include<cmath> using namespace std; #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i) #define per(i,n,a) for (int i=n;i>=a;i--) #define MT(x,i) memset(x,i,sizeof(x) ) #define rev(i,start,end) for (int i=start;i<end;i++) #define inf 0x3f3f3f3f #define mp(x,y) make_pair(x,y) #define lowbit(x) (x&-x) #define MOD 1000000007 #define exp 1e-8 #define N 1000005 #define fi first #define se second #define pb push_back typedef long long ll; const ll INF=0x3f3f3f3f3f3f3f3f; typedef vector <int> VI; typedef pair<int ,int> PII; typedef pair<int ,PII> PIII; ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; } inline int read() { char ch=getchar(); int x=0, f=1; while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while('0'<=ch&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } string s; int vis[200],k,n,t; vector <int> v; int main () { scanf ("%d",&t); while (t--) { v.clear (); scanf ("%d%d",&n,&k); for (int i='a';i<='z';i++) vis[i]=0; cin>>s; for (auto it:s) vis[it]++; int ans=0; rep (i,1,n) { if (k%i==0) { for (int j=1;i*j<=n;j++) { int cnt=0; for (int p='a';p<='z';p++) { cnt+=vis[p]/j; } if (cnt>=i) ans=max (ans,i*j); } } } printf ("%d\n",ans); } return 0; }