2020.06.09——习题训练五

A - Sum of Odd Integers

 题意:

给定一个数n和k,问能否k个不同奇数的和可以等于n,如果可以输出yes,否则输出no

题解:

首先可以知道k个奇数的和是k^2,也就是说如果n<k*k一定是不可能的,然后再判断如果n是偶数k一定也要是偶数不然加起来就是奇数了,同理n是奇数,k也要是奇数。

代码:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
int main(){
    ll t;
    cin>>t;
    while(t--){
        ll n,k;
        int flag1=0,flag2=0;
        cin>>n>>k;
        if(n%2==0){
            flag1=1;
        }
        if(k%2==0){
            flag2=1;
        }
        if(n<k*k){
            cout<<"NO"<<endl;
            continue;
        }
        if(flag1==1&&flag2==1){//n是偶数k是偶数
            cout<<"YES"<<endl;
        }
        else if(flag1==0&&flag2==0){//n是奇数k是奇数
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }    
    }
    return 0;
}

B - Princesses and Princes

 题意:

有n个公主和n个王子,每个公主都有心意的王子列表,国王可以让没有匹配到王子的公主换个目标,如果都能很好的匹配输出OPTIMAL,否则输出IMPROVE然后再输入没有匹配到王子的公主和没有匹配到公主的王子的号数。

题解:

就是一个枚举,先把所有王子的序号存在数组里为0表示没有选到公主,如果这个公主匹配到王子就让a[王子的序号]=1表示选到公主,并且flag=1表示公主选到王子。如果到最后枚举完flag=0,就说明公主没有选到适合自己的王子,再枚举判断下就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,g,p,ans=0;
        int flag;
        cin>>n;
        int a[n+10];
        memset(a,0,sizeof(a));//0表示王子没给选走
        for(int i=0;i<n;i++){
            cin>>g;
            flag=0;//0表示没有选到王子 
            for(int j=0;j<g;j++){
                cin>>p;
                if(a[p-1]==0&&flag==0){
                    a[p-1]=1;
                    flag=1;//选到王子 
                }
            }
            if(flag==0){
                ans=i+1;
            }
        }
        //cout<<ans<<endl;
        if(ans==0){
            cout<<"OPTIMAL"<<endl;
        }
        else{
            for(int i=0;i<n;i++){
                if(a[i]==0){
                    cout<<"IMPROVE"<<endl;
                    cout<<ans<<" "<<i+1<<endl;
                    break;
                }
            }
        }
    }
    return 0;
}

C - EhAb AnD gCd

 题意:

给定x求出gcd(a,b)+lcm(a,b)=x这个式子a和b的任意的值。

题解:

其实1和p的最大公约数是1,而1和p的最小公倍数是p,所以只要1+p=x求出p的值,再把1和p分配到ab上就可以了。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
    ll t;
    cin>>t;
    while(t--){
        ll x;
        cin>>x;
        cout<<1<<" "<<x-1<<endl;
    }
    return 0;
}

D - CopyCopyCopyCopyCopy

题意:

就是判断有多少个递增的数字,比如 1 1 2 3 4 4就有4个(1 2 3 4)

题解:

先用sort讲它们排序下再进行比较,如果这个数大于前面的数就sum++.

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t,n,sum;
    cin>>t;
    while(t--){
        sum=1;
        cin>>n;
        int a[n+10];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        sort(a,a+n);
        int p=a[0];
        for(int i=1;i<n;i++){
            if(a[i]>p){
                sum++;
                p=a[i];
            }
     }
     cout<<sum<<endl;
    }
    return 0;
}

F - Yet Another Tetris Problem

题意:

给定n个方块围成的高度,你有很多的高度为2的方块,如果n个方块都不为0就可以所有方块减一个,不然对为0的方块加上一个高度为2的方块,继续判断,问是否能使得所有方块都为0.

题解:

题目一开始看挺久的,然后发现其实是有规律的只要每个方块的奇偶性不同是不可能消除的,因为加上一个高度为2的方块并不改变奇偶性如1 1 2 1,不论怎么加到最后都是会 0 0 1 0的。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    int flag1,flag2;
    cin>>t;
    while(t--){
        int n;
        flag1=0;
        flag2=0;
        cin>>n;
        int a[n+10];
        for(int i=0;i<n;i++){
            cin>>a[i];
            if(a[i]%2==0){
                flag1++;
            }
            else{
                flag2++;
            }
        }
        //cout<<flag1<<" "<<flag2<<endl;
        if(max(flag1,flag2)==n){//判断偶数和奇数的最多有多少个 如果等于n就表示所有都是奇数或者偶数。
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

G - Yet Another Palindrome Problem

 题意:

给定一个字符串,问它子串(就是不改变顺序的任意3个字符)的是否有长度为3的回文数,如果有输出yes否则输出no。

题解:

对每一个字符都枚举下判断从i+2到n的每一个字符有没有相同的如果有相同的就是长度为3的回文数。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        int flag;
        cin>>n;
        int a[n+10];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        for(int i=0;i<n-2;i++){
            flag=0;
            for(int j=i+2;j<n;j++){
                if(a[i]==a[j]){
                      flag=1;
                      break;
                }
            }
            if(flag==1){
                break;
            }
        }
        if(flag==1){
            cout<<"YES"<<endl; 
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
} 

H - Frog Jumps

 题意:

给定一个字符串由R和L构成如果在R上只能向右跳,在L上只能向左跳,问青蛙一次最多能跳多少步使得能跳出这个字符串。

题解:

不论青蛙如何跳,它都是要从起点到最近的一个R,R到R的距离和R到终点的距离,判断这些距离中最大是多少,它一次最少就要跳这么多格。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    string p;
    cin>>t;
    while(t--){
        cin>>p;
        int d=-1;
        int l=0,l1=p.size()+1;
        for(int i=0;i<p.size();i++){
            if(p[i]=='R'){
                l=max(i-d,l);//起点到R和R到R之间的最大距离
                d=i;
            }
        }
        //cout<<l<<endl; 
        for(int i=p.size()-1;i>=0;i--){
            if(p[i]=='R'){
                l1=min(l1,l1-i-1);//最后一个R到终点的距离
                break;
            }
        }
        cout<<max(l1,l)<<endl;//使用最大的距离
    }
    return 0;
}
原文地址:https://www.cnblogs.com/liyongqi/p/13110097.html