Codeforces Round #650 (Div. 3)(A-F1)题解
A. Short Substrings
题解:按题意模拟即可
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> const int maxn = 3100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1000007; using namespace std; string s; int main() { int t; cin>>t; while(t--){ cin>>s; if(s.size()==2){ cout<<s<<endl; continue ; } cout<<s[0]; for(int i=1;i<s.size()-1;i+=2){ cout<<s[i]; } cout<<s[s.size()-1]<<endl; } return 0; }
B - Even Array
判断一下不符合条件的情况,看看两种不符合条件的情况是否相等,如果相等即可调换,不相等输出-1.
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> const int maxn = 3100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1000007; using namespace std; int a[maxn]; int main() { int t; cin>>t; while(t--){ int n; cin>>n; int cnt=0,cnt1=0; for(int i=0;i<n;i++){ scanf("%d",&a[i]); if(a[i]%2==0&&i%2!=0) cnt++; if(a[i]%2!=0&&i%2==0) cnt1++; } if(cnt!=cnt1) cout<<-1<<endl; else cout<<cnt<<endl; } return 0; }
C - Social Distance
题解:我们把有1的地方扩散一下,也就是假设第i个地方是1,那么i到i+k和i+k是都不可以做人的,那么我们把不能做人的地方用#打个标记即可,然后寻找有0的地方,并且没次在0的地方坐下一个客人,位置要向前移动k个。
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> const int maxn = 3100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1000007; using namespace std; string s; int main() { int t,k,n; cin>>t; while(t--){ cin>>n>>k; cin>>s; for(int i=0;i<n;i++){ if(s[i]=='1'){ for(int j=max(0,i-k);j<=min(n-1,i+k);j++){ s[j]='#'; } } } int ans=0; for(int i=0;i<n;i++){ if(s[i]=='0'){ ans++; i+=k; } } cout<<ans<<endl; } return 0; }
D - Task On The Board
感觉这个题目涉及了一点点思维,但是模拟起来细节有点多。
思路:对于0的位置,字母一定是最大的,对于字母第二大的元素,他只会受第一大字母的影响,同理,第三大字母只受比他大的字母的影响。
所以我们遍历每个位置看看,某个字母是否符合这个位置的b数组的大小
还有一个小细节,就是我们需要看看这个字母最多能匹配多少个位置,如果位置的个数大于当前字母的个数,说明这个字母不可以用。
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> const int maxn = 3100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1000007; using namespace std; char ans[maxn]; string s; int visited[maxn],cnt[maxn]; int a[maxn]; int main() { int t; cin>>t; while(t--){ cin>>s; int n,z=0; cin>>n; memset(cnt,0,sizeof(cnt)); memset(visited,false,sizeof(visited)); char imax='a'; for(int i=0;i<s.size();i++){ cnt[s[i]-'a']++; if(imax<s[i]) imax=s[i]; } for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++){ if(!a[i]) visited[i]=true,z++; } for(int i=25;i>=0;i--){ if(cnt[i]>=z){ for(int j=0;j<n;j++) if(!a[j]) ans[j]=i+'a'; cnt[i]=0; break; } cnt[i]=0; } for(int i=25;i>=0;i--){ if(cnt[i]!=0){ int x=0; for(int j=0;j<n;j++){ if(!visited[j]){ int sum=0; for(int k=0;k<n;k++){ if(visited[k]&&ans[k]>i+'a'){ sum+=abs(j-k); } } if(sum==a[j]){ visited[j]=true; x++; ans[j]=i+'a'; } } } if(x>cnt[i]){ for(int j=0;j<n;j++){ if(ans[j]==i+'a') visited[j]=false; } } } } for(int i=0;i<n;i++) printf("%c",ans[i]); printf("\n"); } return 0; }
E - Necklace Assembly
做的时候也想到过跟因子有关,可惜太菜了,没想出来。
参考了这个大佬的思路:https://www.bilibili.com/video/BV1xT4y1J7yd?p=2
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> const int maxn = 3100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1000007; using namespace std; string s; int cnt[maxn]; int main() { int t; cin>>t; while(t--){ int n,k; cin>>n>>k; cin>>s; memset(cnt,0,sizeof(cnt)); for(int i=0;i<s.size();i++){ cnt[s[i]-'a']++; } vector<int> v; for(int i=1;i<=k;i++){ if(k%i==0) v.push_back(i); } int ans=0; for(int i=1;i<=n;i++){ for(auto x : v){ if(x%i==0){ ans=max(ans,i); } if(i%x==0){ int dx=i/x; int cnt1=0; for(int j=0;j<26;j++){ cnt1+=cnt[j]/dx; } if(cnt1>=x){ ans=max(ans,i); } } } } cout<<ans<<endl; } return 0; }
F1 - Flying Sort (Easy Version)
本题数据较大,所以要事先离散化一下,为什么可以这样离散化,是因为条件给出了每个数字最多出现一次,所以我们把他按照由小到大的顺序分别代表1-n的数字。
在用dp求出最长上升子序列即可。
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> const int maxn = 3100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1000007; using namespace std; int dp[maxn]; int a[maxn],b[maxn]; map<int,int> mp; int main() { int t; cin>>t; while(t--){ int n; cin>>n; memset(dp,0,sizeof(dp)); mp.clear(); for(int i=0;i<n;i++){ scanf("%d",&a[i]); b[i]=a[i]; mp[b[i]]=i; } sort(b,b+n); for(int i=0;i<n;i++){ a[mp[b[i]]]=i; } int imax=1; for(int i=0;i<n;i++){ dp[a[i]]=dp[a[i]-1]+1; imax=max(imax,dp[a[i]]); } cout<<n-imax<<endl; } return 0; }
题解 文章被收录于专栏
主要写一些题目的题解