题意简述:数组a经过一系列操作之后获得数组b,给你数组b,构造出一个满足条件的数组a
操作如下从左到右扫描数组a,如果是一个素数,那么把第这个素数的素数加到数组a中,例如a[1]=2那么加3到数组a当中
如果是一个和数,那么把这个和数的最大因数加进去,这个因数不能等于他本身
只操作N次,N为数组a的长度,操作之后打乱b数组
题解:需要一定的思维,我们考虑一些特殊的值,比如最大值,然后如果是素数,那么说明他是操作1加进去的,然后我们就可以知道是哪个数产生了他
如果不是素数,说明他就是数组a中的数
然后就出来了,另外如果我们去考虑最小值是出不来的,因为情况不止一种
很多问题都可以用这种方式来得到答
int v[maxn+5],prime[maxm],tot; int Rank[maxn]; void init(){ for(int i=2;i<maxn;i++){ if(!v[i]) v[i]=i,prime[++tot]=i; for(int j=1;j<=tot && i<=maxn/prime[j];j++){ v[i*prime[j]]=prime[j]; if(i%prime[j]==0) break; } } for(int i=1;i<=tot;i++) Rank[prime[i]]=i; } int cnt[maxn]; int main(){ init(); int n; cin>>n; for(int i=0;i<2*n;i++){ int x; scanf("%d",&x); cnt[x]++; } for(int i=maxn-1;i>=0;i--){ for(int j=0;j<cnt[i];j++){ if(v[i]==i) { printf("%d ",Rank[i]); cnt[Rank[i]]--; } else { printf("%d ",i); cnt[i/v[i]]--; } } } }
案,就是考虑一些特殊的值,要牢记于心