Codeforces Round #410(Div.2)题解
A.扫一遍,O(n)即可
注意点:1.一定要修改一次
2.字符串长度为奇数时也可以修改中间一个
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 using namespace std; 5 string s; 6 char c[100]; 7 int len,cnt; 8 int main(){ 9 cin>>s; 10 len=s.length(); 11 for (int i=1; i<=len; i++) c[i]=s[i-1]; 12 for (int i=1; i<=(len/2); i++) if (c[i]!=c[len-i+1]) cnt++; 13 if (cnt==0 && len % 2==1) cout<<"YES"<<endl; 14 else if (cnt!=1) cout<<"NO"<<endl; 15 else cout<<"YES"<<endl; 16 return 0; 17 }
B.模拟
官方题解貌似用的dp
我用了三个map维护了一下,也是可以的。
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<map> 5 #include<algorithm> 6 using namespace std; 7 const int inf=2147483640; 8 int n,len,aa; 9 string s[100],now,tmp; 10 map <string,int> mp; 11 map <string,int> cnt; 12 map <string,int> ans; 13 int main(){ 14 ios::sync_with_stdio(false); 15 cin>>n; 16 aa=inf; 17 for (int i=1; i<=n; i++) cin>>s[i]; 18 len=s[1].length(); 19 for (int i=1; i<=n; i++) { 20 tmp=s[i]; 21 now=tmp; 22 if (cnt[now]!=i) { 23 mp[now]++; 24 cnt[now]=i; 25 tmp=now; 26 } 27 for (int j=1; j<len; j++) { 28 now=tmp.substr(1,len-1)+tmp[0]; 29 if (cnt[now]!=i) { 30 mp[now]++; 31 cnt[now]=i; 32 tmp=now; 33 ans[now]+=(j % len); 34 } 35 } 36 } 37 map <string,int>::iterator pp; 38 for (pp=mp.begin(); pp!=mp.end(); pp++) { 39 if ((pp -> second)>=n) { 40 string nn=pp -> first; 41 aa=min(aa,ans[nn]); 42 } 43 } 44 if (aa==inf) cout<<"-1"<<endl; 45 else cout<<aa<<endl; 46 return 0; 47 }
下面题感觉出的很不错
C.列一下式子就可以发现:
首先,一定是有可行方案的
其次,只要把每个数改成偶数就可以了
所以说讨论相邻的两数,如果都是奇数
那么只要操作一次,就可以使它们都变成偶数
而如果是一奇一偶,就需要操作两次了。
于是O(n)扫一遍,就解决了!!
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=100010; 6 int n,g,a[maxn],ans; 7 int gcd(int x,int y){ 8 if (x<y) swap(x,y); 9 if (y==0) return x; 10 if (x % y==0) return y; 11 return gcd(y,x % y); 12 } 13 int main(){ 14 scanf("%d",&n); 15 for (int i=1; i<=n; i++) { 16 scanf("%d",&a[i]); 17 g=gcd(g,a[i]); 18 a[i] %= 2; 19 } 20 for (int i=1; i<n; i++) { 21 if (a[i]==1 && a[i+1]==1) { 22 ans++; 23 a[i]=a[i+1]=0; 24 } 25 } 26 for (int i=1; i<=n; i++) if (a[i]==1) { 27 ans+=2; 28 a[i]=0; 29 } 30 if (g>1) { 31 printf("YES\n"); 32 printf("0\n"); 33 } 34 else { 35 printf("YES\n"); 36 printf("%d\n",ans); 37 } 38 return 0; 39 }
D.这道题要找到规律需要思考一会儿。
可以假设一共有奇数个数(偶数个就再加一个a[]=b[]=0就可以了)
原题条件可以转变成这些数的和大于其它数。
把它们按照a的大小递减排序。
第一个加入答案,后面的两两比较,判断它们b值的大小(注意,下标与前面不一样)
并决定选择哪一个。
其实仔细想想还是可以很容易理解的。
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 #define ll long long 5 using namespace std; 6 const ll maxn=100010; 7 struct data{ 8 ll a,b,id; 9 }x[maxn]; 10 bool cmp(const data &u,const data &v) { 11 return u.a > v.a; 12 } 13 ll n; 14 vector <ll> ans; 15 int main(){ 16 scanf("%I64d",&n); 17 for (ll i=1; i<=n; i++) scanf("%I64d",&x[i].a); 18 for (ll i=1; i<=n; i++) scanf("%I64d",&x[i].b),x[i].id=i; 19 sort(x+1,x+n+1,cmp); 20 if (n % 2==0) x[n+1].id=n+1,x[n+1].a=x[n+1].b=0,n++; 21 ans.push_back(x[1].id); 22 for (ll i=2; i<=n; i+=2) { 23 if (x[i].b>x[i+1].b) ans.push_back(x[i].id); 24 else ans.push_back(x[i+1].id); 25 } 26 printf("%d\n",ans.size()); 27 for (ll i=0; i<ans.size(); i++) printf("%I64d ",ans[i]); 28 printf("\n"); 29 return 0; 30 }