技巧:滚动筛法,感觉就像是弄了个缓存区一样,由于每次最多加63,所以用两块大小大于等于63的空间充当缓存区就可以实现筛所有的数了。
wa点:用unique,应该先sort再unique, 并且在lower_bound时注意使用新的尾部点。
tle点: 使用long long 会超时,而int即可,原因应该是long long 输入输出以及位运算更加耗时吧
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL;
int GetSum(int a)
{
int ret=0;
while(a)
{
ret+=a%10;
a/=10;
}
return ret;
}
bool Hash[130]; //滚动筛数组
bool Flag[1000005];
int Ans[5005],S[5005],T[5005];
int main()
{
int n,k,i,j,t,tt,cnt,cnt2,num,cnt3;
while(scanf("%d %d",&n,&k)!=EOF)
{
cnt=0,cnt2=0,cnt3=0;
memset(Hash,false,sizeof(Hash));
memset(Flag,false,sizeof(Flag));
for(i=0;i<k;++i)
{
scanf("%d",&S[i]);
if(Flag[S[i]])
cnt3++;
Flag[S[i]]=true;
T[i]=S[i];
}
sort(T,T+k);
unique(T,T+k); //注意unique后,lower_bound要使用新的终点。 若使用vector,应该先排序后unique
for(i=1;i<=n;++i)
{
j=i&127;
if(!Hash[j])
{
cnt++;
if(Flag[cnt])
Ans[cnt2++]=i;
}
Hash[j]=false;
tt=0,t=i;
while(t)
{
tt+=t%10;
t/=10;
}
// Hash[(j+GetSum(i))&127]=true;
Hash[(j+tt)&127]=true;
}
printf("%d\n",cnt);
for(i=0;i<k;++i)
{
num=lower_bound(T,T+k-cnt3,S[i])-T;
printf("%d%c",Ans[num],i==k-1?'\n':' ');
}
}
return 0;
}