2020年5月18日 习题训练题解

  1. A题:

找规律,用快速幂算一下(2^n/2+1)-2就行了,代码:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int quickmi(int a,int b)

{

    int ans=1,base=a;

    while(b>0)

    {

        if(b&1)

        {

            ans*=base;

        }

        base*=base;

        b>>=1;

    }

    return ans;

}

int main()

{

   int t,n,ans;

   cin>>t;

   while(t--)

   {

       cin>>n;

       ans=quickmi(2,n/2+1)-2;

       cout<<ans<<endl;

   }

    return 0;

}

  1. B题:

设difference代表给出数组不同值的个数,刚开始WA了三次,原因是没考虑最简单的情况difference<k。

题解是用两个数组去重,我是用的set,因为set里面不会存取重复的值。

思路:

difference>k输出-1;

否则将给出数组中的不同值存入set中,对于数组中的每一个值替换为k个数,这k个数是set中的数循环输出。

代码如下:

#include<bits/stdc++.h>

using namespace std;

int main()

{

    int t,n,k,i,j;

    set<int>h;

    set<int>::iterator p;

    cin>>t;

    while(t--)

    {

        h.clear();

        cin>>n>>k;

        int a[100+8];

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

        {

            cin>>a[i];

            h.insert(a[i]);

        }

        int difference=0;

        difference=h.size();

        //cout<<difference<<endl;

        if(difference>k)

        {

            cout<<"-1"<<endl;

        }

        else

        {

            cout<<n*k<<endl;

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

            {

                int flag=0;

                p=h.begin();

                while(1)

                {

                    if(flag==k)

                    {

                        break;

                    }

                    if(p==h.end())

                    {

                        p=h.begin();

                    }

                    cout<<*p<<' ';

                    p++;

                    flag++;

                }

            }

            cout<<endl;

        }

    }

    return 0;

}

  1. C题:

WA了三次,原因是用了int和float,后来仔细一想发现原来可以把乘法变成除法。

思路很简单,就是比较两种方法-1所消耗的钱数,即比较a和b/2的大小,转换一下就是比较2*a和b的大小。

代码:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int quickmi(int a,int b)

{

    int ans=1,base=a;

    while(b>0)

    {

        if(b&1)

        {

            ans*=base;

        }

        base*=base;

        b>>=1;

    }

    return ans;

}

int main()

{

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

  int x,y;

  int a,b;

  cin>>t;

  while(t--)

  {

      cin>>x>>y;

      cin>>a>>b;

      int ma=max(x,y);

      int mi=min(x,y);

      long long sum=0;

      if(2*a>b)

      {

          sum+=(ll)mi*(ll)b+(ll)(ma-mi)*a;

      }

      else

      {

          sum+=((ll)x+(ll)y)*(ll)a;

      }

      cout<<sum<<endl;

  }

    return 0;

}

  1. D题:

分两种情况,第一种就是字符串全为1或全为0,此时直接输出该字符串就行,周期为1.

第二种就是既有0又有1,这时候就要把0和1相间输出,使得周期为2;

代码如下:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int quickmi(int a,int b)

{

    int ans=1,base=a;

    while(b>0)

    {

        if(b&1)

        {

            ans*=base;

        }

        base*=base;

        b>>=1;

    }

    return ans;

}

int main()

{

  string s;

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

  cin>>t;

  while(t--)

  {

      cin>>s;

      size_t f=s.find("1");

      size_t p=s.find("0");

      if(f==s.npos||p==s.npos)

      {

          cout<<s;

      }

      else

      {

          int len=s.size();

         for(i=0;i<len-1;i++)

         {

             cout<<s[i];

             if(s[i]==s[i+1])

             {

                 if(s[i]=='0')

                 {

                     cout<<'1';

                 }

                 else

                 {

                     cout<<'0';

                 }

             }

         }

         cout<<s[len-1];

      }

      cout<<endl;

  }

    return 0;

}

  1. E题:

没有技术含量的模拟题,完全根据题以来做就行。代码:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int quickmi(int a,int b)

{

    int ans=1,base=a;

    while(b>0)

    {

        if(b&1)

        {

            ans*=base;

        }

        base*=base;

        b>>=1;

    }

    return ans;

}

int main()

{

    int n,a,b,c,d,t;

    cin>>t;

    while(t--)

    {

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

        if((a-b)*n>(c+d)||(a+b)*n<(c-d))

        {

            cout<<"No"<<endl;

            continue;

        }

        cout<<"Yes"<<endl;

    }

    return 0;

}

  1. F题:

我原来的思路是先把每个峰的标号记录下来,然后根据标号的差和峰的个数找符合题意的值,后来发现无法实现。

正确思路:先记录每个山是否是峰,是为1,然后前缀和,求出每一段的峰值,然后判断边界是否为峰,是的话峰值-1,最后输出峰值的最大值以及所对应的左端点。

中间WA了两次是因为,没有考虑a[1]>a[0],和没有峰的情况。

代码:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int a[200000+8]={0},b[200000+8];

int flag[200000+8]={0};

int main()

{

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

    cin>>t;

    while(t--)

    {

        memset(flag,0,sizeof(flag));

        cin>>n>>k;

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

       {

           cin>>a[i];

       }

       a[0]=a[1]+1;

       a[n+1]=a[n]+1;

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

       {

           if(a[i]>a[i-1]&&a[i]>a[i+1])

           {

               flag[i]=1;

           }

       }

       int ma=-1,ans=0,sum=0;

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

      {

          flag[i]+=flag[i-1];

      }

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

      {

          if(i+k-1>n)

          {

              break;

          }

          sum=flag[i+k-1]-flag[i-1];

          if(a[i]>a[i+1]&&a[i]>a[i-1])

          {

              sum--;

          }

          if(a[i+k-1]>a[i+k]&&a[i+k-1]>a[i+k-2])

          {

              sum--;

          }

          if(sum>ma)

          {

              ma=sum;

              ans=i;

          }

      }

       cout<<ma+1<<' '<<ans<<endl;

    }

    return 0;

}

原文地址:https://www.cnblogs.com/chengxvzhishen/p/12922386.html