综合训练(2)+字符串
A - Chips Moving
#include<stdio.h> #include<map> #include<iostream> #include<algorithm> using namespace std; const int MAX=1e2+2; int x[MAX],n; /* 如果是奇数,移动:2*n+1,肯定要花1¥ 如果时欧式,移动:2*n,肯定不花钱 只用考虑花的钱 */ int main() { cin>>n; map<int,int>pos; for(int i=0;i<n;++i) { cin>>x[i]; pos[x[i]]++;//记录每个坐标已有的个数 } sort(x,x+n); int len=unique(x,x+n)-x; /* unique的作用是“去掉”容器中相邻元素的重复元素 它会把重复的元素添加到容器末尾(所以数组大小并没有改变) 而返回值是去重之后的尾地址,所以如果想得到去重后的size,需要减去初始地址 unique针对的是相邻元素,所以对于顺序顺序错乱的数组成员,或者容器成员,需要先进行排序 */ int ans=0x3f3f3f3f; int sum; for(int i=0;i<len;++i) { sum=0; for(int j=0;j<len;++j) { if(x[j]!=x[i]) { if(abs(x[i]-x[j])&1) sum+=pos[x[j]]; } } ans=min(ans,sum); } cout<<ans; return 0; }
B - Bad Prices[排序]
两个forTLE,后来以为是LCS,结果就是一个简简单单的排序
#include<stdio.h> #include<map> #include<iostream> #include<algorithm> using namespace std; const int MAX=150000+2; int x[MAX],t,flag,n,s; int main() { cin>>t; while(t--) { cin>>n; s=0; for(int i=0;i<n;++i)cin>>x[i]; flag=x[n-1]; for(int i=n-2;i>=0;--i) { if(flag<x[i]) { s++; } else { flag=x[i]; } } cout<<s<<endl; } return 0; }
C - Book Reading
#include<stdio.h> #include<map> #include<iostream> #include<algorithm> #include<cstring> using namespace std; long long t,m,N,j,n,sum; const int MAX = 20+2; int x[MAX],a[MAX],temp; int main() { cin>>t; while(t--) { cin>>n>>m; if(n<m) { cout<<0<<endl;continue; } N = n/m; sum=0; j=0; temp=0; memset(a,0,sizeof(a)); for(long long i=1;i<=N;i++) { temp=(i*m)%10; x[i]=temp; a[temp]++; if(a[temp]==2) break; sum+=temp; // cout<<">>"<<temp<<endl; j++; } // cout<<">>sum="<<sum<<",N="<<N<<",j="<<j<<endl; sum = sum*(N/j); N=N%j; for(int i=1;i<=N;++i) { sum+=x[i]; } cout<<sum<<endl; } return 0; }
D - Equalizing by Division (easy version)
#include<iostream> #include<algorithm> const int MAX=2E5+7; using namespace std; int c[MAX]; int x[MAX]; int a[MAX]; int n,k,t; int main() { cin>>n>>k; for(int i=0;i<n;++i)cin>>a[i]; sort(a,a+n); int ans=0x3f3f3f3f; for(int i=0;i<n;++i) { t=a[i]; c[t]++; int s=0; while(t) { if(k==c[t]) ans=min(x[t],ans); t/=2;s++; c[t]++; x[t]+=s; } } cout<<ans; return 0; }
E - Equalizing by Division (hard version)
同D
F - Two Small Strings😥
#include<iostream> #include<algorithm> #include<string> #include<cstring> const int MAX=2E5+7; using namespace std; int flag; string a[2],s; int c[3]; int n,nn; void dfs(string t) { if(flag) return ; else if(t.size()>nn) return ; else if(t.find(a[0])!=t.npos||t.find(a[1])!=t.npos) return ; memset(c,0,sizeof(c)); for(int i=0;i<t.size();++i) c[t[i]-'a']++; if(c[0]==n&&c[1]==n&&c[2]==n) { flag=1;s=t;return ; } //cout<<"当前的:"<<t<<"\ta的数量="<<c[0]<<"\tb的数量="<<c[1]<<"\tc的数量="<<c[2]<<endl; for(char i='a';i<'d';++i) dfs(t+i); return ; } int main() { cin>>n; nn=n*3; for(int i=0;i<2;++i)cin>>a[i]; dfs("a"); if(!flag) { dfs("b"); if(!flag) { dfs("c"); if(!flag) { cout<<"NO"<<endl; return 0; } } } cout<<"YES"<<endl<<s<<endl; return 0; }
贴一份大佬的ac代码,直接找可能的n+n+n字符串:来源📣2019个人训练赛-F - Two Small Strings
#include<vector> #include<iostream> #include<string> #include<algorithm> using namespace std; vector<string> arr; int n; string abc="abc",c; int main(){ string s,t; cin>>n>>s>>t; do{ string cur; for(int i=0;i<n;i++) cur+=abc; //有几个a就要循环几轮 arr.push_back(cur); string curr=string(n,abc[0])+string(n,abc[1])+string(n,abc[2]); arr.push_back(curr); //cout<<"这一次的abc="<<abc<<",生成的cur="<<cur<<",生成的curr="<<curr<<endl; }while(next_permutation(abc.begin(), abc.end()));//生成abc的全排列 //生成n+n+n型字符串 for(vector<string>::iterator it=arr.begin();it!=arr.end();it++) { size_type position,position1; c=*it; position =c.find(s); position1=c.find(t); if(position==c.npos&&position1==c.npos){ cout<<"YES"<<endl; cout<<c<<endl; return 0; } } cout<<"NO"<<endl; return 0; }