其他分享
首页 > 其他分享> > 2020.06.01——习题训练4

2020.06.01——习题训练4

作者:互联网

A - Dreamoon and Ranking Collection

题意:给你一个不连续的数组和一个x,每对x减小一,就能对不连续的数组添加一个数,使其连续数加一,问连续的里最大的那个数是几

思路:用统计的方法,记录出现过的每个数,然后开始遍历它,没出现过,x--,补充一个,直到x为零

#include <bits/stdc++.h>
using namespace std;
#define N 1000000
int a[N];
int main(){
  int t;
  cin>>t;
  while(t--){
    int n,x,s;
    cin>>n>>x;
    memset(a,0,sizeof(a));
    for(int i=1;i<=n;i++){
        cin>>s;
        a[s]=1;
    }
  for(int i=1;;i++){
    if(a[i]==0){
        a[i]=1;
        x--;
    }
    if(x==0)break;
  }
  int w;
  for(int i=1;;i++){
    if(a[i]==0)
    {
      cout<<i-1<<endl;
      break;
    }
  }
}
}
View Code

B - Dreamoon Likes Permutations

题意:给你一个无序数组,让你看看是否能分为两部分(1~l1,1~l2),这两部分各部分里所有的数能组成连续的序列,问你能组成几个,输出l1,l2

思路:

设ma为a中所有元素的最大值。如果可以将a序列分解为两个排列p1p1 and p2p2,那么ma必须与l1和l2中最大的那一个值相等。
所以最多有两种情况:

 

1.l1=ma,l2=n−ma

2.l1=n-ma,l2=n−ma(如果ma不是n的一半的话尝试分成n-ma和ma两个部分,就这里懵)

#include<iostream>
using namespace std;
#define N 200000
int a[N],v[N],s[5][5];
int t,ans,n,ma;
bool check(int l1,int l2){
for(int i=1;i<=n;i++) v[i]=0;
for(int i=1;i<=l1;i++) v[a[i]]=1;
for(int i=1;i<=l1;i++){
if(v[i]==0) return 0;
}
for(int i=1;i<=n;i++) v[i]=0;
for(int i=l1+1;i<=n;i++) v[a[i]]=1;
for(int i=1;i<=l2;i++){
if(v[i]==0){
return 0;
}
}
return 1;
}

int main()
{
cin>>t;
while(t--){
cin>>n;
ma=-1000000;
for(int i=1;i<=n;i++){
cin>>a[i];
ma=max(ma,a[i]);
}
ans=0;
if(check(ma,n-ma)){
ans++;
s[ans][1]=ma;
s[ans][2]=n-ma;
}
if(ma*2!=n&&check(n-ma,ma)){
ans++;
s[ans][1]=n-ma;
s[ans][2]=ma;
}
cout<<ans<<endl;
for(int i=1;i<=ans;i++){
printf("%d %d\n",s[i][1],s[i][2]);
}
}
return 0;
}

C - Exercising Walk

题意:先给你四个数a,b,c,d,分别表示左右下上,再给你六个数(三个坐标),经过a,b,c,d之后,坐标不超就是x1<=x<=x2,y1<=y<=y2;

思路:说明最终x=x-a+b;y=y+c-d;但是要注意一点,就是当他们在同一个点,且a,b,c,d不为零时一定不行

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
#define N 1000000
ll a[N],b[N];
int main()
{
    int t;
    cin>>t;
    while(t--){
    int a,b,c,d;
    cin>>a>>b>>c>>d;//左右下上
    int x,y,x1,y1,x2,y2;
    cin>>x>>y>>x1>>y1>>x2>>y2;
    if(x==x1&&x==x2&&(a!=0&&b!=0)||y==y1&&y==y2&&(c!=0&&d!=0)){
        cout<<"NO"<<endl;
    }
   else{int xx,yy;
    xx=x+b-a;
    yy=y+d-c;
    if(xx>=x1&&xx<=x2&&yy>=y1&&yy<=y2)
        cout<<"YES"<<endl;
    else cout<<"NO"<<endl;}
        }

}
View Code

D - Composite Coloring

题意:有相同的质因子的数图相同的颜色(不会超过11种),输出需要几种,及每个数涂色的结果

思路:找到每个数的质因子,只要有相同的就图同种色

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1005
int s=0;//质数个数
int prime[1005];
int mark[1005];
int c[1005];
int color;
int ans[1005];
void get_prime()
{
    for(int i=2;i<=N;i++){
        if(mark[i]==0){
            prime[++s]=i;
        }
            for(int j=1;j<=s&&i*prime[j]<=N;j++){
                mark[i*prime[j]]=1;
                if(i%prime[j]==0)break;
            }

    }
}
int main()
{
  get_prime();
     int t;
    cin >> t;
    while(t--){
        color = 0;
        memset(ans,0,sizeof ans);
        memset(c,0,sizeof c);
        int n;
        cin >> n;
        for(int i = 1; i <= n; ++i){
            int x;
            cin >> x;
            for(int j = 1; j <= s; ++j){//遍历质数
                if(x%prime[j]==0){
                    if(!c[prime[j]])//给没有颜色的素材染上颜色
                       c[prime[j]] = ++color;
                    ans[i] = c[prime[j]];//记录每个合数的颜色
                    break;
                }
            }
        }
        printf("%d\n",color);
        for(int i = 1; i <= n; ++i)
            printf("%d ",ans[i]);
    }
    return 0;}

  

E - K-th Beautiful String

题意:给你两个b,(n-2)个a,问你x这个代表哪种排列

思路:

  1. aaabb
  2. aabab
  3. aabba
  4. abaab
  5. ababa
  6. abbaa
  7. baaab
  8. baaba
  9. babaa
  10. bbaaa 

 只看后一个b发现,是有规律的,1+2+3这种

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
//#define N 1000000
int main()
{
    int t;
    cin>>t;
    while(t--){
ll sum=0,n,x,w=1,p=0,q,m=1;
cin>>n>>x;
for(int i=1;i<=n;i++){
   sum+=i;
if(sum>x){
    sum-=i;
    q=i-1;
    break;
}

}
if(sum==x){
    p=q-1;
}
else {while(sum!=x){
    if((x-sum)==1&&m==1)
    {q+=1;
    m=0;}
        w=0;
    sum++;
    p++;}
    if(w==0){
    p-=1;
}
else p=0;}

//cout<<sum<<" "<<p<<" "<<q<<endl;
for(int i=1;i<=n;i++){
    if(i==(n-q)||i==(n-p))cout<<'b';
    else cout<<'a';
}
cout<<endl;
}

}
View Code

 

  

F - Carouse

 题意:若干数围成一个圈,为他们涂色,若相邻两个数不同,则颜色一定不同,相同无所谓,问最少需要几种颜色

思路:

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+100;
int a[maxn];
int b[maxn];
int main(){
    int t;
    cin>>t;
    while(t--){
            int n;
    cin>>n;
    for(int i=1;i<=n;i++) b[i] = 0;
    for(int i=1;i<=n;i++) cin>>a[i];
    int t = 1;
    int pos = 0;
    b[1] = 0;
    //贪心放
    for(int i=2;i<=n;i++){
        if(a[i] == a[i-1]){
            pos = i;
            b[i] = b[i-1];
        }else{
            t = 2;
            b[i] = !b[i-1];
        }
    }
    //判最后1个
    if(a[n] != a[1] && b[n] == b[1]){ //产生冲突
        if(pos != 0){ //在前面值相同的地方,做一次改变;就使得a[1] a[n]不在冲突
            for(int i=pos;i<=n;i++) b[i] = !b[i]; //pos后面的元素全部取反,全部取反保证方案仍然正确
        }else{
            t = 3; //前面不能改变的话,就只能拿一个新的元素了
            b[n] = 2;
        }
    }
    cout<<t<<endl;
    for(int i=1;i<=n;i++) cout<<b[i]+1<<" ";
    cout<<endl;
    }
    return 0;
}
View Code

 

 

 

标签:01,ma,int,cin,2020.06,&&,ans,习题,include
来源: https://www.cnblogs.com/1324a/p/13046882.html