牛客寒假训练营5 G/H

sakiko的排列构造

链接

题目大意:
有一个排列p,对于i属于1-n,pi = pi+i,且pi要是质数
easy和hard不同就只有n的范围
1<=n<=1e6

分析:
尝试之后发现,找到离pi最近的质数,就会有一溜数可以放好,然后便是规模更小的问题,例如 n = 7,最近的质数是11
,那么7放第4个,6放第5个直到4放第7个,剩下的是n = 3的问题。还有考虑有没有解这个问题,质数有个性质:对于a(>1),在a-2a之间必定存在一个质数,可以保证有解

可能是我太弱了,写的打表+二分没有暴力快

G

#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

int n;
int v[1000080],prime[1000080],cnt=0;
int ans[1000010];
int find(int x){
	int l = 1,r = cnt;
	while(l<=r){
		int mid = (l+r)>>1;
		if(x<prime[mid]) r = mid-1;
		else l = mid+1;
	}
	return prime[l];
}

int main(){
	ios;
	cin>>n;
	for(int i = 2;i<=n*2;++i){
		if(v[i]==0){
			v[i]=i;
			prime[++cnt]=i;
		}
		for(int j = 1;j<=cnt;++j){
			if(prime[j]>v[i]||i*prime[j]>n*2) break;
			v[i*prime[j]]=prime[j];
		}
	}
	int i = n;
	while(i>0){
		int minp = find(i);
		for(int j = minp-i;j<=i;++j) ans[j] = minp-j;
		i = minp-i-1;
	}
	for(int i = 1;i<=n;++i) cout<<ans[i]<<" ";
	return 0;
}

H

#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n;
int ans[1000070];

bool isprime(int x){
	if(x==1) return 0;
	for(int i = 2;i*i<=x;++i){
		if(x%i==0) return 0;
	}
	return 1;
}

void solve(){
	cin>>n;
	int i = n;
	while(i>0){
		int minp = i+1;
		while(!isprime(minp)) minp++;
		//cout<<minp<<" "<<l<<"\n";
		for(int j = i;j>=minp-i;--j) ans[j] = minp-j;
		i=minp-i-1;
	}
	for(int i = 1;i<=n;++i) cout<<ans[i]<<" ";
	cout<<"\n";
}

int main(){
	ios;
	int t=1;
	//cin>>t;
	while(t--){
		solve();
	}

	return 0;
}

当然H也可以过G

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值