Divisibility

给定n个数,问是否能从中选出恰好k个数,使得这些数两两之差可以被m整除。

【输入格式】

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

第一行输入三个正数n,k,m。

接下来一行n个数。

【输出格式】

      若不能选出k个数,则输出"No"(不包含引号)。

      若可以,第一行输出"Yes"(不包含引号),第二行输出k正整数,用空格隔开,如果有多种方案,输出字典序最小的方案。

【数据规模与约定】

对于1~3的测试点:n<=20

对于4~7的测试点:n,m<=3000

对于8~10的测试点:k<=n<=10^6,m<=10^6,ai<=10^9

from 学长LYH

(a-b)%p=0 => a%p=b%p 然后把同余的存起来瞎搞就行了。。。话说multiset为何如此慢。。。好像sort一下就行。。。

#include<cstdio>
#include<iostream>
#include<set>
#define pc(x) putchar(x) 
#define R register int
using namespace std;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,k,m,lst=0x3f3f3f3f,mn;
multiset<int>s[1000001];
bool flg;
signed main() {
    freopen("divisibility.in","r",stdin);
    freopen("divisibility.out","w",stdout);
    n=g(),k=g(),m=g();
    for(R i=1,x;i<=n;++i) x=g(),s[x%m].insert(x);
    for(R i=0,tmp;i<m;++i) if(s[i].size()>=k&&(tmp=*s[i].begin(),tmp<lst)) flg=true,lst=tmp,mn=i;
    R cnt=1; if(flg) { pc('Y'),pc('e'),pc('s'),pc('\n');
        for(multiset<int>::iterator it=s[mn].begin();cnt<=k;++cnt,++it) printf("%d ",*it);    
    } else pc('N'),pc('o'),pc('\n');
}

2019.04.18

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄