cf1176D

题意简述:数组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]]--;
			}	
		}		
	}
}

  

案,就是考虑一些特殊的值,要牢记于心

猜你喜欢

转载自www.cnblogs.com/033000-/p/12329281.html