2020.6.2--习题四

Posted mxw000120

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020.6.2--习题四相关的知识,希望对你有一定的参考价值。

A - Dreamoon and Ranking Collection

 题意:给出n个排名,x个将要进行的比赛数,这x个排名可以任意给出,使名次能为1 2 3  ..v连续的一组数,选取恰当的数使v最大

先将已知排名作为下标且值为1,其余为0,再从1开始筛选数组,其中不为1的赋值为1并记录个数,当个数达到x个时跳出;再将数组重新筛选,遇到0时跳出,最终结果为 i-1;

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x;
        cin>>n>>x;
        int m,i,j,ct=0,b[1010]={0};
        for(i=1;i<=n;i++)
        {
            cin>>m;
            b[m]=1;
        }
        for(i=1; ;i++)
        {
            if(b[i]==0)
            {
                ++ct;
                b[i]=1;
            }
            if(ct==x)break;
        }
        int k=0;
        for(i=1; ;i++)
        {
            if(b[i]==0)
            {
               k=i-1;
               break;
            }
        }
        cout<<k<<endl;
    }
}

 

B - Dreamoon Likes Permutations

给出一个长为n的序列,要求把它分成两部分,两部分均为一个连续的自然数列,问能有几种分法,给出分出来的两部分序列长度。

设这个序列最大值为ma,那么必定有一部分的长度为ma,因为是自然数列数应该从1到ma不重样,所以长度为ma,那么另一部分的长度就是n-ma了,所以我们尝试把序列分成ma和n-ma两个部分,如果ma不是n的一半的话尝试分成n-ma和ma两个部分,设一部分的长度为len,我们只要用个标记数组看1到len是否全部出现即可。

#include<iostream>
using namespace std;
const int maxn=2e5+5;
int a[maxn],vis[maxn],ans[5][5];
int t,cnt,n,ma;

bool check(int l1,int l2){
    for(int i=1;i<=n;i++) vis[i]=0;
    for(int i=1;i<=l1;i++) vis[a[i]]=1;
    for(int i=1;i<=l1;i++){
        if(vis[i]==0) return 0;
    }
    for(int i=1;i<=n;i++) vis[i]=0;
    for(int i=l1+1;i<=n;i++) vis[a[i]]=1;
    for(int i=1;i<=l2;i++){
        if(vis[i]==0){
            //cout<<"****
";
            return 0;
        }
    }
    return 1;
}

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

 

C - Exercising Walk

 题意:有一只猫,开始位置在(x,y),向左右下上分别走a,b,c,d步,可以按任意顺序走,同一个方格可以反复经过,但不能超过(x1,y1)~(x2,y2)这个界限,如果可以安排合理则输出Yes否则输出No

当(x1==x&&x2==x&&a+b!=0)||(y1==y&&y2==y&&c+d!=0) 直接输出No

其余情况下:无论向左还是向右走多少下,最终x=x-a+b,同理y=y-c+d;只要此时x,y都在(x1,y1)~(x2,y2)这个界限内,就输出Yes,否则No

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

    }
}

 

D - Composite Coloring

题意: 用不超过11种颜色给合数数组染色,保证同色的数不互质。
题解: 数组范围1000以内,而100以内的质数共11个。素因子分解按照最小素因子分配颜色。

#include <bits/stdc++.h>
using namespace std;
int res[1010];
map<int,int> mp;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int cnt=0;
        mp.clear();
        for(int i=0,a;i<n;i++){
            cin>>a;
            for(int j=2;j<=sqrt(a);j++){
                if(a%j==0){
                    if(mp[j])res[i]=mp[j];
                    else res[i]=mp[j]=++cnt;
                    break;
                }
            }
        }
        cout<<cnt<<"
";
        for(int i=0;i<n;i++)
            cout<<res[i]<<" ";
        cout<<"
";
    }
    return 0;
}

E - K-th Beautiful String

 题意:给一个长度n的ab字符串,要求包含(n-2)个a和2个b,进行字典序排列,求第k个字符串

思路:

通过找规律,第一个b在倒数第二位有1个,倒数第三位2个,倒数第四位三个,第二个b的位置就是k-1-2-3-...剩下的数字倒着数,循环

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long n,k,i,j;
        scanf("%lld%lld",&n,&k);
        char s[n+10];
        for(i=1;i<n;i++)
        {
            if(k<=i)break;
            else k-=i;
        }
        i=n-i;
        k=n-k+1;
        for(j=1;j<=n;j++)
        {
            if(j==i||j==k)
            {
                cout<<"b";
            }
            else cout<<"a";
        }
        cout<<endl;
    }
}

F - Carousel

 题意: 一个圈中,相邻的不同元素要涂成不同颜色,问最多需要多少种颜色可涂满,并写出涂法

要使答案为1,显然只有一种情况,就是整个序列只有一种动物。

要使答案为2。先把序列里每一段极长的、相同动物的连续段用同一种颜色表示,把相邻的段涂上不同的颜色(例如:上一段是1,这一段就是2;上一段是2,这一段就是1)。

此时,还需要考虑的只有1n的关系。若1和n是同一种动物,或者它们现在已经是不同的颜色了,则说明当前的涂色方法就是一个合法解。

否则,我们要做一些调整,使1和n颜色不同。我们检查序列里是否存在一个同色段的长度大于1。如果存在,则我们可以把这一段劈成两半,前一半还是原来的颜色,后一半和原来颜色相反,且从它往后的每一段颜色都和原来反转。这样,1n就一定不同色了。

如果找不到长度大于1的同色段。说明我们无法用22种颜色构造出合法解。即答案为3。我们直接在原来构造的基础上令n的颜色为3即可。

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mk make_pair
#define lob lower_bound
#define upb upper_bound
#define fi first
#define se second
#define SZ(x) ((int)(x).size())

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;

namespace Fread{
const int MAXN=1<<20;
char buf[MAXN],*S,*T;
inline char getchar(){
    if(S==T){
        T=(S=buf)+fread(buf,1,MAXN,stdin);
        if(S==T)return EOF;
    }
    return *S++;
}
}//namespace Fread
#ifdef ONLINE_JUDGE
    #define getchar Fread::getchar
#endif
inline int read(){
    int f=1,x=0;char ch=getchar();
    while(!isdigit(ch)){if(ch==-)f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
inline ll readll(){
    ll f=1,x=0;char ch=getchar();
    while(!isdigit(ch)){if(ch==-)f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
/*  ------  by:duyi  ------  */ // myt天下第一
const int MAXN=2e5;
int n,a[MAXN+5],col[MAXN+5];
bool check1(){
    for(int i=1;i<=n;++i){
        int j=i%n+1;
        if(a[i]!=a[j])return 0;
    }
    puts("1");
    for(int i=1;i<=n;++i)printf("%d ",1);puts("");
    return 1;
}
bool check2(){
    col[1]=1;
    for(int i=2;i<=n;++i){
        if(a[i]!=a[i-1]){
            col[i]=3-col[i-1];
        }
        else{
            col[i]=col[i-1];
        }
    }
    if((a[n]==a[1])||(a[n]!=a[1]&&col[n]!=col[1])){
        puts("2");
        for(int i=1;i<=n;++i)printf("%d ",col[i]);puts("");
        return 1;
    }
    for(int i=1;i<n;++i)if(a[i]==a[i+1]){
        col[i+1]=3-col[i];
        for(int j=i+2;j<=n;++j){
            if(a[j]!=a[j-1]){
                col[j]=3-col[j-1];
            }
            else{
                col[j]=col[j-1];
            }
        }
        puts("2");
        for(int i=1;i<=n;++i)printf("%d ",col[i]);puts("");
        return 1;
    }
    return 0;
}
void check3(){
    col[1]=1;
    for(int i=2;i<=n;++i){
        if(a[i]!=a[i-1]){
            col[i]=3-col[i-1];
        }
        else{
            col[i]=col[i-1];
        }
    }
    col[n]=3;
    puts("3");
    for(int i=1;i<=n;++i)printf("%d ",col[i]);puts("");
}
int main() {
    int T=read();while(T--){
        n=read();
        for(int i=1;i<=n;++i)a[i]=read();
        if(check1())continue;
        if(check2())continue;
        check3();
    }
    return 0;
}

 

以上是关于2020.6.2--习题四的主要内容,如果未能解决你的问题,请参考以下文章

2020.6.2--习题四

验证码逆向专栏极验三代四代点选类验证码逆向分析

验证码逆向专栏某验四代文字点选验证码逆向分析

验证码逆向专栏某验四代消消乐验证码逆向分析

第一章 反汇编简介

第一章 反汇编简介