A题,可以理解为给n个数,还有x个任意的数,让找出可以组成从1到m的最大的m;就用set吧n个数存起来,在从1开始遍历,如果可以找到那个数就不用管,找不到的话就用任意数,如果没有任意数就结束。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x;
        cin>>n>>x;
        set<int>p;
        for(int i=0;i<n;i++)
        {
            int a;
            cin>>a;
            p.insert(a);
        }
        int ans=0;
        for(int i=1;i<1000;i++)
        {
            if(p.find(i)==p.end())
            {
                if(x==0)break;
                ans++;
                x--;
                p.insert(i);
            }
            else
            {
                ans++;
            }
        }
        cout<<ans<<endl; 
    }
}

 

B题,给定一个序列,将他分成两部分,每一部分都包含从1到n的数,求有几种可能分离的情况,仔细想一下,只有三种情况,第一种不能分成,第二种有一种方法,第三种有两种方法,先判断元素的个,如果有0个或者三个或者一个小的数有一个并且大的有两个都是不能分成的,记录最大的有两个元素的数,在从前遍历到那个最大的数,存进set里,如果set中的元素等于那个数,并且没有比它大的就成立,在从后面遍历一次即可。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int b[200000];
        vector<int>p;
        p.clear();
        for(int i=0;i<=n;i++)
        {
            b[i]=0;
        }
        int flag=0,max=0;
        for(int i=0;i<n;i++)
        {
            int a;
            cin>>a;
            p.push_back(a);
            if(a>max)max=a;
            b[a]++;
        }
        int num=1e9;
        for(int i=1;i<=max;i++)
        {
            if(b[i]>2||b[i]==0||flag==1&&b[i]>=2)
            {
                flag=2;
                break;
            }
            if(b[i]==1)
            {
                if(i<num)num=i-1;
                flag=1;
            }
            if(b[i]==2&&flag==0&&i==max)
            {
                num=i;
                flag=1;
             } 
        }
        
        if(num==0)flag=2;
        if(flag==2)cout<<0<<endl;
        else
        {
            int ans=0;
            set<int>v,v2;
            for(int i=0;i<num;i++)
            {
                v.insert(p[i]);
                v2.insert(p[n-i-1]);
            }
            if(v.size()==num&&v.upper_bound(num)==v.end())
            {
                ans++;
            }
            if(v2.size()==num&&v2.upper_bound(num)==v2.end())
            {
                ans++;
            }
            if(v.size()==n-num&&ans==2)
            {
                ans=1;
                cout<<ans<<endl;
                cout<<v.size()<<" "<<v2.size()<<endl;
            }
            else
            {
                cout<<ans<<endl;
            if(v.size()==num&&v.upper_bound(num)==v.end())cout<<num<<" "<<n-num<<endl;
            if(v2.size()==num&&v2.upper_bound(num)==v2.end())cout<<n-num<<" "<<num<<endl; 
            }
            
        }    
    }
}

 

C题,如果向下的步数大于向上的那么起点距离最下面的那个y点的距离一定要大于向下的步数减向上的步数,同理判断向上,左,右的条件,还有就是如果上下端点值相等但是向上走的步数和向下走的步数不为0也不行,左右同理,剩下的就是可以的了。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        LL x,y,x1,y1,x2,y2;
        cin>>x>>y>>x1>>y1>>x2>>y2;
        LL num1=x-x1,num2=x2-x,num3=y-y1,num4=y2-y;
        int flag=0;
        if(a>b&&a-b>num1||a<b&&b-a>num2||c>d&&c-d>num3||d>c&&d-c>num4)flag=1;
        if(x2==x1&&a+b!=0||y1==y2&&c+d!=0)flag=1;
        if(flag==0)cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}

 

D题,打表观察之后,发现一千以内的数(除了素数)都可以被11个数整除,,找出那些数,然后再将可以整除某个数的数放在一起就可以。

#include<bits/stdc++.h>
using namespace std;
int c[14]={2,3,5,7,11,13,17,19,23,29,31};
int check(int b)
{
    for(int i=0;i<14;i++)
    {
        if(b%c[i]==0)return i+1;
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        set<int>p;
        int a[1005],d[14],e[14];
        int num=0;
        for(int i=0;i<14;i++)d[i]=0;
        for(int i=0;i<n;i++)
        {
            int b;
            cin>>b;
            a[i]=check(b);
            p.insert(a[i]);
            d[a[i]]=1;
        }
        e[0]=0;
        for(int i=1;i<12;i++)
        {
            if(d[i]==0)
            e[i]=e[i-1]+1;
            else e[i]=e[i-1];

        }
        num=p.size();
        cout<<num<<endl;
        for(int i=0;i<n;i++)cout<<a[i]-e[a[i]]<<" ";
        cout<<endl;
    }
    
}

 

E题,先观察例子,前面的b先向前移动,后面的b在向前面的b移动,前面的a移动之后,后面的b总是在最后移动,根据等差数列求和公式,求出k比num个数的和大,第一个b就在n-num那里,第二个b就还有k-num个数的和步,b的位置确定剩下的就是a的位置 了。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        LL n,k;
        cin>>n>>k;
        string s;
        for(int i=0;i<n;i++)
        {
            s+='a';
        }
        LL num=0;
        for(LL i=2;i<1000000;i++)
        {
            if(i*(i-1)>=2*k)
            {
                num=i;
                break;
            }
        }
        s[n-num]='b';
        num=k-((num-1)*(num-2))/2;
        s[n-num]='b';
        cout<<s<<endl;
         
    }
}

 

F题,其实只有三种情况,第一种,只有一个数,都输出1就行,第二种,有两个或以上个数,但是是偶数,就有两个数,如果都输出1 2那么每个与前一个或后一个都不同,如果是奇数,如果有两个相邻的数相同,那么把那两个看做一个数,也可以只用两个数解决问题,第三种,就是有奇数个数但是每个数与相邻的都不同,那么前面输出 1 2循环,最后一个数输出3就可以。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int a[200005],num=0,flag=0,jj=0;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            if(i!=0&&a[i]!=a[i-1])num++;
            if(i!=0&&a[i]==a[i-1])jj=1;
        }
        if(num==0)
        {
            cout<<1<<endl;
            for(int i=0;i<n;i++)cout<<1<<" ";
            cout<<endl;
        }
        else
        {
            if(a[0]==a[n-1]||n%2==0)
            {
                cout<<2<<endl;
                for(int i=0;i<n;i++)
                {
                    if(i%2==0)cout<<"1"<<" ";
                    else cout<<"2"<<" ";    
                }
                cout<<endl;
            }
            else
            {
                if(jj==0)cout<<3<<endl;
                else cout<<2<<endl;
                int flag=0;
                flag=1;
                cout<<1<<" ";
                for(int i=1;i<n;i++)
                {
                    if(a[i]==a[i-1]&&flag==1)
                    {
                        flag=0;
                        if(i%2==1)cout<<"1"<<" ";
                        else cout<<"2"<<" ";
                        continue;
                    }
                    if(i==n-1&&flag==1)break;
                    if(flag==1)
                    {
                        if(i%2==0)cout<<"1"<<" ";
                        else cout<<"2"<<" ";
                    }
                    else
                    {
                        if(i%2==0)cout<<"2"<<" ";
                        else cout<<"1"<<" ";
                    }
                }
                if(flag==1)cout<<"3"<<" ";
                cout<<endl;
            }
        }
    }
}

 

posted on 2020-06-03 10:12  小灰灰的父亲  阅读(261)  评论(0)    收藏  举报