陈瑜推荐的好题。
就是给你一个数字串,让你找到一个字典序最小的串,满足这串中的数组两两互质,并且字典序不小于原串。
#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=2e6+10;
using namespace std;
int n,a[maxn],prime[maxn],cnt[maxn];
bool b[maxn];
void init()
{
mem(b,true);
b[0]=false;b[1]=false;
for(int i=2;i<maxn;i++)
{
if(b[i])
{
for(int j=2;i*j<maxn;j++)
b[i*j]=false;
}
}
int cnt=0;
for(int i=1;i<maxn;i++)
if(b[i])
prime[++cnt]=i;
}
bool ok(int k)
{
int ret=true;
for(int i=2;i<=sqrt(a[k]);i++)
{
if(b[i]&&(a[k]%i==0))
{
if(cnt[i]>=1)
ret=false;
}
int pp=a[k]/i;
if(a[k]%pp==0&&b[pp])
if(cnt[pp]>=1)
ret=false;
}
if(b[a[k]]==true&&cnt[a[k]]>=1) ret=false;
if(ret==false) return false;
for(int i=2;i<=sqrt(a[k]);i++)
{
if(b[i]&&(a[k]%i==0))
cnt[i]++;
int pp=a[k]/i;
if(a[k]%pp==0&&b[pp])
cnt[pp]++;
}
if(b[a[k]])
cnt[a[k]]++;
return true;
}
void print()
{
printf("%d",a[1]);
for(int i=2;i<=n;i++)
printf(" %d",a[i]);
puts("");
}
int main()
{
mem(cnt,0);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
init();
int p=-1;
for(int i=1;i<=n;i++)
if(ok(i)==false)
{p=i;break;}
if(p==-1)
{print();return 0;}
int num=a[p];
for(int i=num+1;i<=maxn;i++)
{
a[p]=i;
if(ok(p))
break;
}
int q=1;
for(int i=p+1;i<=n;i++)
{
for(int j=q;j<=maxn;j++)
{
if(b[j]==true&&cnt[j]==0)
{a[i]=j;q=j+1;cnt[j]++;break;}
}
}
print();
return 0;
}