zoukankan      html  css  js  c++  java
  • 新生赛002赛后补题

    G - 0011  

    NBUT - 1626 

    这道题考察的是字符数组、字符串方面的知识。我在字符数组、字符串上的知识比较薄弱,一开始就卡在了要如何输入这串字符上,没想到直接开一个字符数组,用cin输入就可以了。 

    在思维方面上,这题主要考验我们找特点、总结,找规律的能力。

    根据题意所述,我们可以发现,一个合法的字符串要有相同数量的0和1,而且0在1前。可以概括为:

    前面有几个连续的0,后面就有几个连续的1。
    后面有几个连续的1,前面就有几个连续的0。

    发现了这一点后就很简单了,下面上代码。

    #include<iostream>
    #include<cstring>
    using namespace std;
    char s[1006];//开比1000大一点的字符数组
    int l;
    int main()
    {
      int n;
      cin>>n;
      while(n--)
      {
        l=0;
        int q=1;
        cin>>s;
        for(int i=0;i<=strlen(s)-1;i++)
        {
          if(s[i]=='1') l--;//字符型用得是''
          else if(s[i]=='0') l++;
          if(l<0) q=0;//在过程中后面连续的1多于前面连续的0 不合法
        }
        if(l>0) q=0;//前面连续的0多于后面连续的1 不合法
        if(q==0) printf("NO ");
        else printf("YES ");
      }
      return 0;
    }

    E - 由你来决定怎么颁奖

     CodeForces - 1264A 

    这道题目的文字量也很大,而且题目还在最后还多加了一个条件,容易忽略:让奖牌的数量在满足其他条件的基础上最大。

    i.e.是“换句话说、也就是说”的意思。补充:e.g.=for example。

    题目大意是:在金牌数量小于银牌和铜牌的数量,并且获奖人数不能超过总人数的一半的基础上,让你去分配奖牌,使奖牌的数量最大。如果分配不了,则输出"0 0 0"。

    这种题目就按题目的意思模拟一遍就ok了。

    至于如何实现请见代码,不多bb了。

    #include<iostream>
    using namespace std;
    int p[400010];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n;
            int g=0,s=0,br=0;
            scanf("%d",&n);
            int mid=n/2;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&p[i]);
            }
            if(n<10) { printf("0 0 0
    "); continue; }
            while(p[mid]==p[mid+1]) mid--;   
            int a=1,b=1;
            for(int i=1;i<=mid-1;i++)
            {
                if(p[i]!=p[i+1]) 
                {
                    if(a==1) a=0;
                    else if(b==1) 
                    {
                        if(s>g) b=0;
                        else s++;
                    }
                }
                if(p[i]==p[i+1])
                {
                    if(a==1) g++;
                    else if(b==1) s++;
                }
            }
            g++;s++;br=mid-g-s;
            if(g<s&&g<br) printf("%d %d %d
    ",g,s,br);
            else printf("0 0 0
    ");
        }
    }  

    F - XorXor

     NBUT - 1615 

    这道题只要你知识点都掌握了就不难。

    知识点:异或运算——分别比较两个数的二进制的各个位数是否相同,若不同,则此位为1,若相同则此位为0。在C语言里," ^ "即异或运算符,可以直接使用。

    容易发现:一个相同的数异或偶数次等于0,异或奇数次等于它本身。

    Tip:一般先递增,达到一个最大值后,再递减的类似二项式展开式的数列各项都满足类似i*(n-i+1)的式子。

    #include<iostream>
    using namespace std;
    int a[100010];
    int b[100010];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
            }
            for(int i=1;i<=n;i++)
            {
                int f=i*(n-i+1);
                if(f%2==0) b[i]=0;
                else if(f%2==1) b[i]=a[i];
            }
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                ans^=b[i];
            }
            printf("%d
    ",ans);
        } 
    }

     

    D - Eat Candies

    CodeForces - 1263A

    这道题是道找数学本质题,也可以说是思维转换题。

    题目的大意是给你三种不同的糖果,且三种不同的糖果的数量不确定。让你输入每种糖果的数量,问每天吃两种不同的糖果、每种一颗,最多可以吃几天。

    那么,我们可以将这个问题转换成数学模型:给你三个数,使它们相互抵消,抵消至最小的绝对值要抵消几次(每次抵消1)。

    于是,我们可以想到让最大值-第二大和最小值。但是又有一个问题,那就是这个值可能是负的,绝对值不小。这就说明,最小值中的部分数浪费了。

    这三个数是可以拆开的。那么我们将浪费的数分成两份,一份用来帮助第二大值抵消最大值,一份可以抵消剩下的第二大的值。这样最后的值不是0就是1,即绝对值最小了。

    注意这里的最大、第二大、最小都是不严格的。我们求的是这个过程中相互抵消的次数。

    看清了问题的本质,代码实现就很容易了,下面上代码。

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int main()
    {
      int t;
      int s[4];
      scanf("%d",&t);
      while(t--)
       {
        for(int i=1;i<=3;i++)
        {       scanf(
    "%d",&s[i]);     }
        sort(s
    +1,s+4);     int sum=s[1]+s[2];     if(sum>s[3]) printf("%d ",s[3]+(sum-s[3])/2);     else printf("%d ",sum);   } return 0; }

     H - Perfect String

     CodeForces - 1265A 

    这道题的文字量比较大,一开始看上去,会觉得好像很难的样子。但是,只要你读懂了题目的意思,其实并不难。考验的是你的读题、概括题意的能力。

    题目的大意就是给你a、b、c三个元素,让你将任意一串含有‘?’的字符串改成任意相邻元素不相同的字符串,如果改不了,则输出"-1"。

    那么只要从头开始判断当前元素是否和后一个元素是否相同,若相同,则输出"-1",结束判断。如果遇到"?",则将它换成一个与前后均不相同的元素。若在此过程中,没有中断判断,则输出改好的字符串。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    char str[100005];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int q=1;
            scanf("%s",str);//这里不需要加&符号
            int len=strlen(str);//注意函数不能写在for循环的括号里,这样会导致超时的
            for(int i=0;i<=len-1;i++)
            {
                if(str[i]==str[i+1]&&str[i]!='?') {printf("-1
    ");q=0;break;}
                else if(str[i]=='?') 
                {
                    if(str[i-1]!='a'&&str[i+1]!='a') str[i]='a';
                    else if(str[i-1]!='b'&&str[i+1]!='b') str[i]='b';
                    else if(str[i-1]!='c'&&str[i+1]!='c') str[i]='c';
                }              
            }
            if(q==1) printf("%s
    ",str);
        }
    return 0; 
    }
  • 相关阅读:
    hdu 5795 A Simple Nim 博弈sg函数
    hdu 5724 Chess 博弈sg+状态压缩
    hdu 3094 A tree game 树上sg
    2017"百度之星"程序设计大赛
    hdu 6134 Battlestation Operational 莫比乌斯反演
    HDU 6143 Killer Names DP+快速密
    HDU 6107 Typesetting 倍增
    HDU 6096 String 排序 + 线段树 + 扫描线
    HDU 6086 Rikka with String AC自动机 + DP
    HDU 6073 Matching In Multiplication dfs遍历环 + 拓扑
  • 原文地址:https://www.cnblogs.com/Cnxz/p/12146622.html
Copyright © 2011-2022 走看看