Codeforces 水题糊做#1

感觉自己对于CF的Div2CD难度的题做的还不够好,所以开个坑练习一下吧.

6/20

1.Codeforces 1006D. Two Strings Swaps

根据题意规则大力分类讨论。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 using namespace std;
13 int n;
14 char s1[N],s2[N];
15 int ans;
16 int read()
17 {
18     int s=0,t=1; char c;
19     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
20     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
21     return s*t;
22 }
23 ll readl()
24 {
25     ll s=0,t=1; char c;
26     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
27     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
28     return s*t;
29 }
30 int main()
31 {
32     n=read();
33     scanf("%s",s1+1); scanf("%s",s2+1);
34     if (n&1){
35       if (s1[n/2+1]!=s2[n/2+1]) ans++;
36     }
37     for (int i=1;i<=n/2;i++){
38       if (s1[i]==s1[n-i+1]&&s2[i]==s2[n-i+1]) continue;
39       if (s1[i]==s2[i]&&s1[n-i+1]==s2[n-i+1]) continue;
40       if (s1[i]==s2[n-i+1]&&s2[i]==s1[n-i+1]) continue;
41       if (s1[i]==s1[n-i+1]&&s2[i]!=s2[n-i+1]) {
42           ans+=2;
43           if (s1[i]==s2[i]||s1[n-i+1]==s2[n-i+1]) ans--; continue;
44       }
45       if (s2[i]==s2[n-i+1]&&s1[i]!=s1[n-i+1]) {
46           ans++; continue;
47       }
48       if (s1[i]==s2[i]&&s1[n-i+1]!=s2[n-i+1]) {
49         ans++; continue;
50       }
51       if (s1[i]!=s2[i]&&s1[n-i+1]==s2[n-i+1]) {
52         ans++; continue;
53       }
54       if (s1[i]==s2[n-i+1]&&s2[i]!=s1[n-i+1]) {
55           ans++; continue;
56       }
57       if (s2[i]==s1[n-i+1]&&s1[i]!=s2[n-i+1]) {
58           ans++; continue;
59       }
60       ans+=2;
61     }
62     out(ans);
63     return 0;
64 }
65     
66       
View Code

 

2.Codeforces 1005C. Summarize to the Power of Two

n个数,对于一个数a[i],如果没有a[j](i!=j)使得a[i]+a[j]为2的幂次方则删去,求要删去多少个数.

读入的时候把数都扔到map里,对于一个数枚举2的幂次方并减去这个数得到num,在map里查询num是否存在.需要注意的是当num==a[i]时要判断a[i]出现次数是否大于1.

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d",a)
10 #define writeln printf("\n")
11 const int N=1e5+20050;
12 using namespace std;
13 map<int,int>cnt;
14 int n;
15 int a[N];
16 int num,ans;
17 bool flag;
18 int read()
19 {
20     int s=0,t=1; char c;
21     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
22     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
23     return s*t;
24 }
25 ll readl()
26 {
27     ll s=0,t=1; char c;
28     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
29     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
30     return s*t;
31 }
32 int main()
33 {
34     n=read();
35     for (int i=1;i<=n;i++)
36       a[i]=read(),cnt[a[i]]++;
37     for (int i=1;i<=n;i++){
38         flag=false;
39       for (int j=30;j>=0;j--){
40           num=1<<j;
41           if (cnt.count(num-a[i])>0) {
42               flag=true;
43             if ((a[i]<<1)==num) {
44                 if (cnt[a[i]]==1) ans++; 
45             }
46             break;
47         }
48       }
49       if (flag) continue;
50       ans++;
51     }
52     out(ans);
53     return 0;
54 }
55                 
View Code

 3.Codeforces 1005E1. Median on Segments (Permutations Edition)

思维好题啊QAQ

给一个1到n的排列和一个数k,求中位数为k的区间有多少个.(区间大小m为偶数时,中位数为第m/2个数)

经典套路就是把等于k的看做0,小于k看做-1,大于k看做1,然后计算一遍前缀和.

那么只要计算多少个区间和为0或和为1即可.

和为0很好理解,那么为什么和为1也要计算呢?

证明一波:由于区间一定包含k这个数,所以区间前缀和数组中一定有0,当区间大小为奇数时,区间和为0说明-1和1数量相等,此时k为中位数,区间大小为偶数时,由于含有一个0,所以-1和1的数量不可能相等,也就是和不可能为0,因为中位数是向下取整,1的数量要比-1数量多1,即和为1.

做到这里就不会了。。n2复杂度是爆炸的.

然后我还是看了一丢丢题解。。

因为区间包含k,我们不妨把区间看做a+k+b的形式(当然a,b可以是空集),预处理出右边区间b和k的前缀和数组扔到map里面,然后枚举左区间map查询与左区间的前缀和数相等或相差1的个数.

答案会爆int,所以记得开long long.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%lld",a)
10 #define writeln printf("\n")
11 const int N=2e5+50;
12 using namespace std;
13 map<int,int>cnt;
14 int n,k;
15 int a[N],b[N],sum[N];
16 int num;
17 ll ans;
18 int read()
19 {
20     int s=0,t=1; char c;
21     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
22     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
23     return s*t;
24 }
25 ll readl()
26 {
27     ll s=0,t=1; char c;
28     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
29     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
30     return s*t;
31 }
32 int main()
33 {
34     n=read(),k=read(); 
35     for (int i=1;i<=n;i++){
36       a[i]=read();
37       if (a[i]>k) b[i]=1;
38       else if (a[i]<k) b[i]=-1;
39       if (a[i]==k) num=i;
40       sum[i]=sum[i-1]+b[i];
41       if (i>=num&&num) cnt[sum[i]]++;
42     }
43     for (int i=0;i<=num-1;i++)
44       ans+=cnt[sum[i]]+cnt[sum[i]+1];
45     out(ans);
46     return 0;
47 }
48       
View Code

 4.Codeforces 996D. Suit and Tie

一到n的数,每种数有两个,求交换相邻位置的数使得数字相同的数位置相邻.

考虑两个相同数相邻最少也是他们位置差的绝对值减1,这样直接交换的话并不会改变其他数的顺序,甚至会使原来隔一个数的情况变得相邻,也就是说直接交换答案不会增加甚至会减少.

那么扫一遍交换位置统计答案即可.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d ",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 using namespace std;
13 int n,num,ans=0;
14 int a[N],cnt[N];
15 int read()
16 {
17     int s=0,t=1; char c;
18     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
19     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
20     return s*t;
21 }
22 ll readl()
23 {
24     ll s=0,t=1; char c;
25     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
26     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
27     return s*t;
28 }
29 int main()
30 {
31     n=read();
32     for (int i=1;i<=2*n;i++)
33       a[i]=read();
34     for (int i=1;i<=2*n;i+=2){
35       if (a[i]!=a[i+1]){
36           for (int j=i+1;j<=2*n;j++)
37             if (a[j]==a[i]){
38                 num=j; break;
39             }
40             ans+=num-i-1;
41             for (int j=num;j>i+1;j--)
42               swap(a[j],a[j-1]);
43         }
44     }
45     out(ans);
46     return 0;
47 }
View Code

 5.Codeforces 991D. Bishwock

求有多少个由0组成的L。

如果出现竖着的两个0在同一列,贪心优先考虑往左边找再往右边找,统计答案.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%d ",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 using namespace std;
13 int n,len;
14 int ans;
15 char s[2][N];
16 bool flag;
17 int read()
18 {
19     int s=0,t=1; char c;
20     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
21     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
22     return s*t;
23 }
24 ll readl()
25 {
26     ll s=0,t=1; char c;
27     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
28     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
29     return s*t;
30 }
31 int main()
32 {
33     scanf("%s",s[0]);
34     scanf("%s",s[1]);
35     len=strlen(s[0]);
36     for (int i=0;i<len;i++)
37       if (s[0][i]=='0'&&s[1][i]=='0'){
38           flag=false;
39           for (int j=0;j<2;j++){
40             if (s[j][i-1]=='0') {
41           ans++,s[j][i-1]='X',flag=true;
42           break;
43         }
44       }
45       if (flag) s[0][i]=s[1][i]='X';
46       else {
47         for (int j=0;j<2;j++){
48             if (s[j][i+1]=='0') {
49           ans++,s[j][i+1]='X',flag=true;
50           break;
51         }
52       }
53       if (flag) s[0][i]=s[1][i]='X';
54       }
55     }
56     out(ans);
57     return 0;
58 }
View Code

 6.Codeforces 1015D. Walking Between Houses

有1~n的房子,求走k个回合步数刚好为s的方案.

略带思维的贪心题,大概就是先把大步的走完,然后剩下的一步步走.

细节很多也说不清楚,看代码吧==

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <queue>
 7 #include <map>
 8 #define ll long long
 9 #define out(a) printf("%lld ",a)
10 #define writeln printf("\n")
11 const int N=1e5+50;
12 using namespace std;
13 ll n,m,k,x,p,num,now,a,b,c;
14 ll ans=0;
15 ll s;
16 int read()
17 {
18     int s=0,t=1; char c;
19     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
20     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
21     return s*t;
22 }
23 ll readl()
24 {
25     ll s=0,t=1; char c;
26     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
27     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
28     return s*t;
29 }
30 int main()
31 {
32     n=readl(),k=readl(),s=readl();
33     if (k==s) {
34         puts("YES");
35       for (int i=1;i<=k;i++)
36         if (i&1) cout<<2<<' ';
37         else cout<<1<<' ';
38         return 0;
39     }
40     if (k>s||(n-1)*k<s){
41       puts("NO"); return 0;
42     }
43     else {
44         puts("YES"); now=x=1;
45       a=s/(n-1); b=s-a*(n-1); c=k-a;//剩c回合可走,还有b步要走 
46       if (b>=c) {
47         for (int i=1;i<=a;i++)
48           if (i&1) out(n),now=n,x=-1;
49           else out(1),now=1,x=1;
50           if (b!=c) {
51             c--; now+=(b-c)*x; out(now); 
52           }
53           for (int i=1;i<=c;i++)
54             if (now<n) {
55               if (i&1) out(now+1);
56               else out(now);
57             }
58             else if (now==n){
59               if (i&1) out(now-1);
60               else out(now);
61             }
62         }
63         else {
64            while (b<c){
65              a--; b+=n-1;
66              c++;
67            }
68           for (int i=1;i<=a;i++)
69           if (i&1) out(n),now=n,x=-1;
70           else out(1),now=1,x=1;
71           if (b!=c) {
72           c--; now+=(b-c)*x; out(now);} 
73           for (int i=1;i<=c;i++)
74             if (now<n) {
75               if (i&1) out(now+1);
76               else out(now);
77             }
78             else if (now==n){
79               if (i&1) out(now-1);
80               else out(now);
81             }
82         }
83       }
84     return 0;
85 }
View Code

 

posted @ 2018-07-27 14:10  Kaleidoscope233  阅读(235)  评论(0编辑  收藏  举报