Codeforces Round #486 (Div. 3)

24 篇文章 1 订阅
19 篇文章 0 订阅

链接:http://codeforces.com/contest/988
来源:Codeforces

A - Diverse Team

  找到一个数组中不同的数字是否大于等于>k个,如果满足输出YES,并且输出他们的位置,否则输出NO,遍历去重即可。

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

typedef long long LL;
const int Max_n=110;
int a[Max_n];

struct B{
    int val,pos;
}b[Max_n];

int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int cnt=1;
    b[cnt].val=a[1];
    b[cnt++].pos=1;
    bool flag=false;
    for(int i=2;i<=n;i++){
        bool flag1=false;
        for(int j=1;j<cnt;j++){
            if(a[i]==b[j].val){
                flag1=true;
                break;
            }
        }
        if(!flag1){
            b[cnt].val=a[i];
            b[cnt++].pos=i;
        }
    }
    if(cnt-1>=k) flag=true;
    if(flag){
        printf("YES\n");
        for(int i=1;i<=k;i++)
            printf("%d%c",b[i].pos,i==k?'\n':' ');
    }else{
        printf("NO\n");
    }
    return 0;
}

B - Substrings Sort (string)

  判断短的字符串是否是长的字符串的字串,用string的find函数即可解决。

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

typedef long long LL;
const int Max_n=110;

string a[Max_n];
bool cmp(string &a,string &b){
    return a.length()<b.length();
}

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+n+1,cmp);//按照字符串的长短进行排序
    //for(int i=1;i<=n;i++)
    //    cout<<a[i]<<endl;
    bool flag=true;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(i==j) continue;
            string::size_type pos=a[j].find(a[i]);
            //从第一个字符串开始,寻找其在后面的字符串中是否出现。
            //返回a[j].npos说明a[i],在a[j]这个字符串中没有出现。
            if(pos==a[j].npos) flag=false;
        }
    }
    if(flag){
        cout<<"YES"<<endl;
        for(int i=1;i<=n;i++)
            cout<<a[i]<<endl;
    }else{
        cout<<"NO"<<endl;
    }
    return 0;
}

C - Equal Sums

  给你k个序列,让你判断其中是否存在两个序列可以满足这样的条件:在这两个序列中分别去除一个元素后,这个两个序列的和相等。

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

const int Max_n=200005;
typedef long long LL;
typedef pair<int,int>P;//相当于结构体
map<int,P>m;
int a[Max_n];

int main(){
    int k;
    scanf("%d",&k);
    bool flag=false;
    for(int i=1;i<=k;i++){
        int n,sum=0;
        scanf("%d",&n);
        for(int j=1;j<=n;j++){
            scanf("%d",&a[j]);
            sum+=a[j];//求出每个序列的和
        }
        for(int j=1;j<=n;j++){
            if(flag) break;//标记是否找到了满足条件的两个序列,如果已经找到就跳出判断
            if(m.count(sum-a[j])&&m[sum-a[j]].first!=i){
            //二分的查找sum-a[j]之前已经出现过的次数,并且之前的和不是由当前这个序列产生的
                printf("YES\n");
                printf("%d %d\n",m[sum-a[j]].first,m[sum-a[j]].second);//输出之前的序列值
                printf("%d %d\n",i,j);//当前的序列值。
                flag=true;
            }
            m[sum-a[j]]=P(i,j);//将每一个和的位置都记录下来
        }
    }
    if(!flag)   printf("NO\n");
    return 0;
}

D - Points and Powers of Two

  题目给你一个序列,让你找到其中存在最长的自己满足这样的条件:每两个数的差都是2k,满足条件的子集的个数最多有三个数,并且他们是一个等差数列,也就是说这三个数满足x x+2k x+2k+2k
证明:https://www.cnblogs.com/WTSRUVF/p/9531118.html

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

typedef long long ll;
const int Max_n=2e5+10;
ll a[Max_n];
set<ll>s;

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        s.insert(a[i]);//去重
    }
    bool flag=false;
    for(int i=1;i<=n;i++){
        for(ll j=1;j<=2e9+10;j*=2){//二分的去查找满足条件的数
            if(s.count(a[i]+j)&&s.count(a[i]+j+j)){
                printf("3\n");
                printf("%lld %lld %lld\n",a[i],a[i]+j,a[i]+2*j);
                flag=true;
                break;
            }
        }
        if(flag) break;
    }
    if(!flag){//没有找到3个数,判断是否有两个数满足
        for(int i=1;i<=n;i++){
            for(ll j=1;j<=2e9+10;j*=2){
                if(s.count(a[i]+j)){
                    printf("2\n");
                    printf("%lld %lld\n",a[i],a[i]+j);
                    flag=true;
                    break;
                }
            }
            if(flag) break;
        }
    }
    if(!flag) printf("1\n%lld\n",a[1]);
    return 0;
}

E - Divisibility by 25

  给你一个数,你能够交换其中相邻的数,问你最少交换多少次后这个数能够被25整除。我们知道一个数能够被25整除,那么他的后两位数一定是00,25,50,75,那么我们可以将这四种情况的交换次数全部求出来,然后找到最小的交换次数即可。还要注意如果交换完成后,判断是否有前导零的出现。

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

typedef long long ll;
char a[20],b[20];

int get_times(char x,char y,int n,int ans){
    for(int i=0;i<n;i++) b[i]=a[i];
    bool flag_a=false,flag_b=false;
    int cnt=0;
    for(int i=n-1;i>=0;i--){//有多个满足条件的数,从最后一个开始找
        if(b[i]==y){
            flag_b=true;
            for(int j=i;j<n-1;j++){
                swap(b[j],b[j+1]);
                cnt++;
            }
            break;
        }
    }
    for(int i=n-2;i>=0;i--){
        if(b[i]==x){
            flag_a=true;
            for(int j=i;j<n-2;j++){
                swap(b[j],b[j+1]);
                cnt++;
            }
            break;
        }
    }
    if(flag_a&&flag_b){//两个都找到了,说明次数被更新了
        if(b[0]!='0')
            ans=min(ans,cnt);
        else{
            for(int i=0;i<n-2;i++){
                if(b[i]!='0'){
                    cnt+=i;
                    ans=min(ans,cnt);
                    break;
                }
            }
        }
    }
    return ans;
}

int main(){
    scanf("%s",a);
    int n=strlen(a);
    int ans=100;
    ans=get_times('0','0',n,ans);
    ans=get_times('2','5',n,ans);
    ans=get_times('5','0',n,ans);
    ans=get_times('7','5',n,ans);
    if(ans==100) printf("-1\n");
    else printf("%d\n",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值