zoukankan      html  css  js  c++  java
  • 习题训练计划 2020 06 01

    A题:

    最大的难点在于对题意的理解,带入样例去就不难理解了。

    思路就是用计数法记录一下整个数组,然后从1开始遍历,如果a[i]==0,就令a[i]=1,同时sum++,直到sum==x跳出循环,但要注意此时i之后还有可能a[i]==1,原因就是原数组中存在数比i大,此时我们只要从i开始继续循环,直到a[j]==0,跳出。答案就是j-1。

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    int main()

    {

        int t,n,x,i,j,k;

        cin>>t;

        while(t--)

        {

            cin>>n>>x;

            int a[1000]={0};

            for(i=1;i<=n;i++)

            {

                cin>>k;

                a[k]=1;

            }

            int sum=0;

            for(i=1;;i++)

            {

                if(a[i]==0)

                {

                    sum++;

                    a[i]=1;

                }

                if(sum==x)

                {

                    break;

                }

            }

            for(j=i;;j++)

            {

                if(a[j]==0)

                {

                    break;

                }

            }

            cout<<j-1<<endl;

        }

        return 0;

    }

    B题:WA了5次,最后还是在题解的帮助下做出来的。

    思路:先找出给定数组中的最大值ma,然后依次判断将排列分为ma和n-ma以及分为n-ma和ma是否符合题意。判断方法为用两个map分别记录前半段和后半段数字出现的次数,如果次数!=1,就return false,最后输出结果即可。

    WA的主要原因是没有考虑前半段或后半段出现相同的数的情况,所以map不能>1.

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    int a[200000+8];

    bool check(int x,int y)

    {

        int i,j,k;

        map<int,int >h,u;

        for(i=1; i<=x; i++)

        {

            h[a[i]]++;

        }

        for(i=x+1; i<=x+y; i++)

        {

            u[a[i]]++;

        }

        for(i=1; i<=x; i++)

        {

            if(h[i]!=1)

            {

                return false;

            }

        }

        for(i=1; i<=y; i++)

        {

            if(u[i]!=1)

            {

                return false;

            }

        }

        return true;

    }

    int main()

    {

        int t,i,j,k,n,m;

        cin>>t;

        while(t--)

        {

            int ans=0;

            scanf("%d",&n);

            int ma=0;

            for(i=1; i<=n; i++)

            {

                scanf("%d",&a[i]);

                ma=max(ma,a[i]);

            }

            int f=0,g=0;

            if(check(ma,n-ma))

            {

                ans++;

                f=1;

            }

            if(check(n-ma,ma))

            {

                ans++;

                g=1;

            }

            if(f||g)

            {

                if(n==ma*2)

                {

                    cout<<1<<endl;

                    cout<<ma<<' '<<ma<<endl;

                    continue;

                }

                else

                {

                    cout<<ans<<endl;

                    if(f)

                    {

                        cout<<ma<<' '<<n-ma<<endl;

                    }

                    if(g)

                    {

                        cout<<n-ma<<' '<<ma<<endl;

                    }

                }

            }

            else

            {

                cout<<0<<endl;

            }

        }

        return 0;

    }

    C题:

    水题,思路:主要主要判断最后的落点在哪,因为运动过程中可以用向相反的方向移动来抵消,比如向左一次,再向右一次,向左x要-,向右x要+,向上y要+,向下y要-,所以我么只要比较x-左+右和y-下+上和边界点的大小大小即可。需要注意的是如果向左或向右的步数不等于0,同时左边和右边的边界还相等,这时肯定是”NO”,因为这只猫根本无法在左右方向移动,向上和向下的时候类似。

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    int a[200000+8],b[200000+8];

    int main()

    {

       int t,n,i,j,k,m;

       cin>>t;

       while(t--)

       {

           int a,b,c,d,x,y,x1,x2,y1,y2;

           cin>>a>>b>>c>>d;

           cin>>x>>y>>x1>>y1>>x2>>y2;

           if(x1==x2&&a!=0&&b!=0||y1==y2&&c!=0&&d!=0)

           {

               cout<<"NO"<<endl;

               continue;

           }

           int heng=0,zong=0;

           heng=-a+b;

           zong=-c+d;

           x+=heng;

           y+=zong;

           if(x>=x1&&x<=x2&&y>=y1&&y<=y2)

           {

               cout<<"YES"<<endl;

           }

           else

           {

               cout<<"NO"<<endl;

           }

       }

        return 0;

    }

    D题:

    题目的大意就是给定 nn 个数,要求将其分为不超过 11组,保证每组里面两两不互质。

    首先是一个比较重要的规律:任意一个合数都能写成多个质数的乘积。

    所以我们只需要把能够整除同一质数的分为一类即可。

    对于任意一个合数a,把它写成a=b*c的形式,那么势必有b<=sqrt(a),c>=sqrt(a),所以我们只需要把能够整除较小的那个质数的分为一类即可,由于a最大的取值为1000,所以sqrt(1000)之内的质数有2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59。

    用数组d【j】来表示颜色j是第几个出现的,从而最终得到一共使用了多少个颜色。用数组c[i]表示这个位置所用的颜色.

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    int a[200000+8],b[200000+8];

    int main()

    {

       int t,n,m,i,j,k,a[2000];

       cin>>t;

       int b[12]={0,2,3,5,7,11,13,17,19,23,29,31};

       int c[2000];

       while(t--)

       {

           int d[12]={0};

           cin>>n;

           int ma=0;

           int ans=0;

           for(i=1;i<=n;i++)

           {

               cin>>a[i];

               for(j=1;j<12;j++)

               {

                   if(a[i]%b[j]==0)

                   {

                      if(d[j]==0)

                      {

                          ans++;

                          d[j]=ans;

                         

                      }

                      c[i]=d[j];

                      break;

                   }

               }

           }

           cout<<ans<<endl;

           for(i=1;i<=n;i++)

           {

               cout<<c[i]<<' ';

           }

           cout<<endl;

       }

        return 0;

    }

    E题:

    考虑b的位置,通过枚举b的位置来得到第k个排列。

    首先我们设从左往右数第一个b的位置是x,第二个是y,我们可以发现x的取值范围是1~n-1,y的取值范围是2~n。而且x的规律是从n-1开始递减,直到1

    ,y的规律是从n开始递减,直到x+1.

    另外我们可以发现对于确定的x,他所对应的字符串的数量是一定的,即n-x,所以我们只需要从后往前枚举,用sum记录字符串的数量,每次sum+n-i,直到sum>=k,则x=i,y=n-(k-sum)+1,然后从1到n遍历,把x和y的位置输出b,其余的输出a即可。

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    int a[200000+8],b[200000+8];

    int main()

    {

       int t,n,k,i,j,m;

       cin>>t;

       while(t--)

       {

           cin>>n>>k;

           int sum=0,x,y;

           for(i=n-1;i>=1;i--)

           {

               sum+=n-i;

               if(sum>=k)

               {

                   x=i;

                   sum-=n-i;

                   m=k-sum;

                   y=n-m+1;

                   break;

               }

           }

           for(i=1;i<=n;i++)

           {

               if(i==x||i==y)

               {

                   cout<<"b";

               }

               else

               {

                   cout<<"a";

               }

           }

           cout<<endl;

       }

        return 0;

    }

    F题:

    做不出来,参考的题解。,一个重要的要求就是相邻不同类型的图形颜色不同且所用颜色数最小。

    思路:

    1. 所有的图案相同:

    答案为1,所有的颜色为1.

    1. 有图案不同

    【1】      n为偶数

    答案为2,1,2间隔输出即可

    【2】      n为奇数

    (1)      存在相邻图案相同的

    将其中一对相邻图案输出相同,其他不管

    (2)      出最后一个外,其他1,2间隔输出。

    代码如下:

    #include<bits/stdc++.h>

    using namespace std;

    typedef long long ll;

    int a[200000+8],b[200000+8];

    int main()

    {

        int t,i,j,k,n,m;

        cin>>t;

        while(t--)

        {

            cin>>n;

            int ans=1;

            for(i=1; i<=n; i++)

            {

                cin>>a[i];

            }

            b[1]=1;

            for(i=2; i<=n; i++)

            {

                if(a[i]!=a[i-1])

                {

                    ans=2;

                    break;

                }

            }

            if(ans==1)

            {

                cout<<1<<endl;

                for(i=1; i<=n; i++)

                {

                    cout<<1;

                    if(i!=n)

                    {

                        cout<<" ";

                    }

                }

                cout<<endl;

            }

            else

            {

                int f=1;

                for(i=2; i<=n; i++)

                {

                    if(a[i]==a[i-1])

                    {

                        f=0;

                    }

                }

                if(a[n]==a[1])

                {

                    f=0;

                }

                if(n%2==0)

                {

                    f=0;

                }

                if(f==0)

                {

                    ans=2;

                    if(n%2==0)

                    {

                        for(i=2; i<=n; i++)

                        {

                            if(b[i-1]==1)

                            {

                                b[i]=2;

                            }

                            else

                            {

                                b[i]=1;

                            }

                        }

                    }

                    else

                    {

                       int g=1;

                       for(i=2;i<=n;i++)

                       {

                           if(g&&a[i]==a[i-1])

                           {

                               b[i]=b[i-1];

                               g=0;

                           }

                           else if(b[i-1]==1)

                           {

                               b[i]=2;

                           }

                           else

                           {

                               b[i]=1;

                           }

                       }

                    }

                }

                else

                {

                    ans=3;

                    for(i=2;i<n;i++)

                    {

                        if(a[i]==a[i-1])

                        {

                            b[i]==b[i-1];

                        }

                        else

                        {

                            if(b[i-1]==1)

                            {

                                b[i]=2;

                            }

                            else

                            {

                                b[i]=1;

                            }

                        }

                    }

                    b[n]=3;

                }

                cout<<ans<<endl;

                for(i=1;i<=n;i++)

                {

                    if(i!=1)

                    {

                        cout<<" ";

                    }

                    cout<<b[i];

                }

                cout<<endl;

        }

        }

        return 0;

    }

  • 相关阅读:
    python(六):反射
    python模块之contexlib
    python(五):元类与抽象基类
    python之hashlib模块
    python(四):面型对象--类的特殊方法
    20145226夏艺华 《Java程序设计》第1周学习总结
    20145226夏艺华 《Java程序设计》第10周学习总结
    20145226夏艺华 《Java程序设计》实验报告四
    20145226夏艺华 《Java程序设计》第9周学习总结
    20145226夏艺华 《Java程序设计》第8周学习总结
  • 原文地址:https://www.cnblogs.com/chengxvzhishen/p/13041105.html
Copyright © 2011-2022 走看看