zoukankan      html  css  js  c++  java
  • 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("
    ")
    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("
    ")
    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("
    ")
    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("
    ")
    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("
    ")
    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("
    ")
    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
  • 相关阅读:
    JS 数组排序
    曾经跳过的坑------replace、替换斜杠反斜杠、时间格式化处理
    List排序、集合排序
    git远程覆盖本地的
    整理日期,整理时间段,将日期集合整理为时间段
    当数据库查询in使用超过1000个的处理方式,in超过1000的问题
    oracle一些语法
    idea中git操作
    idea鼠标放上去查看注释,idea查看注释
    idea更新git远程代码,查看代码改动了哪些
  • 原文地址:https://www.cnblogs.com/Kaleidoscope233/p/9377300.html
Copyright © 2011-2022 走看看