Beta Round #61-D: Petya and His Friends

問題概要

n(<50)が与えられる。gcd(a[i],a[j])!=1, gcd(a[0],...,a[n-1])=1, a[i]!=a[j]を満たす数列(上界10^100)を出力する問題。

解法

n=2は解なしであることに注意。

  • すぐ思いつく解法:素数を小さい順にp[0],...,p[n-1]ととってくる。a[i]=(Πp[k])/p[i]とする。本番中は10^100を越えてしまうような気がして書かなかったけど、そんなことは無かった。
  • 賢い解法:a[0]=10, a[1]=15, a[2]=6, a[3]=12, a[4]=18, ...
  • 怪しげな解法:nを2進表記してどうたらこうたら。本番中にこんな解き方をしたせいで大分時間をとられた。どう考えても解法1で10^100を越えないかテストする方が速かった。
int ans[55];

int gcd(int x,int y){
    return y==0?x:gcd(y,x%y);
}

int main(){
    int i,N,m;
    __builtin_scanf("%d",&N);
    if(N==2){
        __builtin_printf("-1");
        return 0;
    }
    m = (1<<(32-__builtin_clz(N-1)))-1;
    for(i=0;i<N;i++) ans[i] = 1;
    for(i=0;i<N;i++) ans[i] *= ((i>>0)&1)?2:3;
    if(N>(1<<1))for(i=0;i<N;i++) ans[i] *= ((i>>1)&1)?3:5;
    if(N>(1<<2))for(i=0;i<N;i++) ans[i] *= ((i>>2)&1)?5:7;
    if(N>(1<<3))for(i=0;i<N;i++) ans[i] *= ((i>>3)&1)?7:11;
    if(N>(1<<4))for(i=0;i<N;i++) ans[i] *= ((i>>4)&1)?11:13;
    if(N>(1<<5))for(i=0;i<N;i++) ans[i] *= ((i>>5)&1)?13:17;
    for(i=0;i<N;i++)if((i&1) && (m&(~i)) < N && gcd(ans[i] ,ans[m&(~i)])==1){
        ans[m&(~i)] *= 19; ans[i] *= 19; 
    }
    for(i=0;i<N;i++) __builtin_printf("%d\n",ans[i]);
    return 0;
}