2019 ACM训练计划——( 每天5题 ) 训练计划20 【gcd求等差数列公差 + strstr函数判断字符串子串】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_42429718/article/details/102682167

A

Codeforces Round #595 (Div. 3), problem: (C1) Good Numbers (easy version)


题目大意

题目意思是找到一个大于等于n的数,并且越小越好 然后满足那个数是由3的幂求和得到的 注意3的幂次只能存在一个


题解

解法一:递归求解

#include<bits/stdc++.h>
using namespace std;
int t,n;
int f(int x){
    if(x==0) return 1;
    if(x%3>1) return 0;
    return f(x/3);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        while(!f(n))
            ++n;
        cout<<n<<endl;
    }
    return 0;
}

解法二:贪心求解

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int t,n;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        int nn=n;
        int cnt=0;
        while(nn!=0){
            nn/=3;
            cnt++;
        }
        int sum=0;
        for(int i=cnt;i>=0;i--)
            sum+=pow(3,i);
        for(int i=cnt;i>=0;i--){
            if(sum-pow(3,i)>=n)
                sum-=pow(3,i);
        }
        cout<<sum<<endl;
    }
    return 0;
}

B

Codeforces Round #595 (Div. 3), problem: (A) Yet Another Dividing into Teams


题目大意

n个学生 分别有不同的编程技能,然后编程技能之间差值等于1的两个同学不能处于同一团队 问这些学生的最小团队


题解

math

排序,然后遍历一遍,判断是否存在两个同学的编程技能相差为1,如果存在的话那就是两个团队 如果不存在差值为1的话,那就所有同学处于一个团队中

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int maxn=1000;
int a[maxn],n,t,cnt=0;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    while(t--){
        cnt=0;
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>a[i];
        sort(a,a+n);
        for(int i=0;i<n-1;i++){
            if(a[i+1]-a[i]==1)
                cnt++;
        }
        if(cnt)
            cout<<2<<endl;
        else
            cout<<1<<endl;
    }
    return 0;
}

C

A - Bazinga


题目大意

给你n个字符串 问你最大的位置:当前位置以前存在一种情况 不是当前字符串的子串


题解

strstr函数很方便 用来判断字符串子串问题 都可以用这函数使用

#include<bits/stdc++.h>
using namespace std;
int t,n;
const int maxn=2019;
char s[520][maxn];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    int k=0;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>s[i];
        int ans=-1;
        for(int i=n;i>=2;i--){
            if(!strstr(s[i],s[i-1])){
                    ans=max(ans,i);
                for(int j=i+1;j<=n;j++){
                    if(!strstr(s[j],s[i-1]))
                        ans=max(ans,j);
                }
            }
        }
        cout<<"Case #"<<++k<<": ";
        if(ans==-1)
            cout<<-1<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}

D


题目大意

给定n个位置(1 — n),每个位置只能建造一个塔。现在位置a和b已经建好了塔,已知每次可以新建塔的前提——能够找到两个塔j和k使得 i = j-k || i = j+k。
现在给出一个博弈局面,当某个人不能再建造塔时为输。问你谁能赢。


题解

当且仅当 a和b处于某个等差数列(差值不为1)时,才无法使得所有位置都建上塔。相反,则n个位置均可建塔。等差数列的差值 d = gcd(a, b),求出可以建塔的个数就可以了

#include<bits/stdc++.h>
using namespace std;
int t,n,a,b;
int gcd(int a, int b){
    return b == 0 ? a : gcd(b, a % b);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>t;
    int k=0;
    while(t--){
        cout<<"Case #"<<++k<<": ";
        cin>>n>>a>>b;
        int t=gcd(a,b);
        t=n/t-2;
        if(t&1)
            cout<<"Yuwgna"<<endl;
        else
            cout<<"Iaka"<<endl;
    }
    return 0;
}

E


题目大意

求让三个人汇集的最短距离


题解

水题

排序,找中间值,然后求相差的绝对值之和即可

#include<bits/stdc++.h>
using namespace std;
int a[5];
int main(){
    cin>>a[0]>>a[1]>>a[2];
    sort(a,a+3);
    cout<<(int)abs(a[1]-a[0])+(int)abs(a[1]-a[2])<<endl;
    return 0;
}
学如逆水行舟,不进则退

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/102682167