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 } 
posted @ 2017-04-25 23:59  MoerBlack  阅读(197)  评论(0编辑  收藏  举报