Educational Codeforces Round 96 (Rated for Div. 2)
原题链接https://codeforces.com/contest/1430
A - Number of Apartments
将一个数分为3,5,7。将这个数对3取余,余数为0时则其可全部由3组成;余数为1时,取出两个3组成一个7;余数为2时,取出一个3组成一个5。特殊情况:1、2、4无法拆分
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main() 5 { 6 int t; 7 cin>>t; 8 int n; 9 while(t--) 10 { 11 cin>>n; 12 if(n==1||n==2||n==4) 13 { 14 cout<<"-1"<<endl; 15 continue; 16 } 17 int a=0,b=0,c=0; 18 a=n/3; 19 int mod=n%3; 20 if(mod==1) 21 { 22 a-=2; 23 c++; 24 } 25 else if(mod==2) 26 { 27 a-=1; 28 b++; 29 } 30 cout<<a<<" "<<b<<" "<<c<<endl; 31 } 32 return 0; 33 }
B - Barrels
贪心,每次将最大的两个数加起来
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 bool amp(int x,int y) 6 { 7 return x>y; 8 } 9 const int maxn=2e5+10; 10 int a[maxn]; 11 int main() 12 { 13 int t; 14 int n,k; 15 cin>>t; 16 while(t--) 17 { 18 cin>>n>>k; 19 for(int i=1;i<=n;i++) cin>>a[i]; 20 sort(a+1,a+n+1,amp); 21 long long ans=0; 22 for(int i=1;i<=k+1;i++) 23 { 24 ans+=a[i]; 25 } 26 cout<<ans<<endl; 27 } 28 return 0; 29 }
C - Numbers on Whiteboard
每次取最大的两个数,除第一次,后面每次都会减1。例如:9和8,计算之后得到9,再取9和7,计算之后得到8,再取8和6,计算之后得到7,以此类推,最后3和1计算得2。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main() 5 { 6 int t; 7 cin>>t; 8 int n; 9 while(t--) 10 { 11 cin>>n; 12 cout<<2<<endl; 13 int flag=n; 14 for(int i=n-1;i>=1;i--) 15 { 16 cout<<flag<<" "<<i<<endl; 17 flag=(flag+i+1)/2; 18 } 19 } 20 return 0; 21 }
D - String Deletion
贪心,第一步先将连在一起的相同的字符去掉,使第二步尽量去掉单独的字符,两个指针变量分别表示这两步进行的位置,第二步指针不能大于第一步的。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int maxn=2e5+10; 6 int f[maxn]; 7 int main() 8 { 9 int t; 10 cin>>t; 11 int n; 12 string s; 13 while(t--) 14 { 15 cin>>n; 16 cin>>s; 17 f[1]=1; 18 int num=1; 19 for(int i=1;i<n;i++) 20 { 21 if(s[i]==s[i-1]) f[num]++; 22 else 23 { 24 num++; 25 f[num]=1; 26 } 27 } 28 // cout<<endl; 29 // for(int i=1;i<=num;i++) cout<<f[i]<<" "; 30 // cout<<endl<<endl; 31 int head=1,tail=1; 32 long long ans=0; 33 int pd=1; 34 while(head<=num) 35 { 36 while(f[head]==1||f[head]==0) 37 { 38 // cout<<head<<" "<<ans<<endl; 39 head++; 40 if(head>num) 41 { 42 pd=0; 43 break; 44 } 45 } 46 if(pd==0) break; 47 f[head]--; 48 f[tail]=0; 49 tail++; 50 ans++; 51 } 52 // cout<<ans<<" wfasf" <<endl; 53 ans+=(num-tail+2)/2; 54 cout<<ans<<endl; 55 } 56 return 0; 57 }
E - String Reversal
类似于冒泡,但是和冒泡不相同,在本题中有的值不需要交换。将字符串反序,每次将所需的字符交换至第一个位置,并将其在字符串中去掉,则个操作实现了初始位置的递增,交换完之后更新记录的字符位置。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 using namespace std; 6 int a[30]; 7 int cnt[30]; 8 int main() 9 { 10 int n; 11 string s; 12 cin>>n; 13 cin>>s; 14 s=' '+s; 15 string r=s; 16 long long ans=0; 17 for(int i=1;i<=n;i++) 18 { 19 int t=s[i]-'a'+1; 20 if(a[t]==0) a[t]=i; 21 cnt[t]++; 22 } 23 // for(int i=1;i<=26;i++) cout<<cnt[i]<<' '; 24 // cout<<endl; 25 for(int i=n;i>0;i--) 26 { 27 int t=r[i]-'a'+1; 28 ans+=a[t]-1; 29 s.erase(a[t],1); 30 cnt[t]--; 31 for(int j=1;j<=26;j++) 32 { 33 if(a[j]>a[t]) a[j]--; 34 } 35 if(cnt[t]==0) a[t]=0; 36 else 37 { 38 while(s[a[t]]-'a'+1!=t) 39 a[t]++; 40 } 41 } 42 cout<<ans<<endl; 43 return 0; 44 }

浙公网安备 33010602011771号