2010年10月30日土曜日

TopCoder 練習

AfraidOfEven(Member SRM 485 Div1 Easy)

■問題
Sashaはある等差数列{ai}を黒板に書いた.偶数が嫌いなPashaは,数列上の各数aiを偶数でなくなるまで2で割り続け,biとした.Pashaによって書き換えられた数列{bi}から元の数列{ai}を求めよ.候補が複数存在する場合は,辞書式順に最も早いものを答えとせよ.

■解法
1. a0=b02m,a1=b12nと決定する.
2. 公差d=a1-a0が求まるので,ai>=2が実現可能かを調べる.具体的には,ai=a0+di=bi2kであるので,(a0+di)/biが2のべき乗となるかどうか.
3. 全候補の内,辞書式順に最も早いものを答えとする.

計算時間は,a0,a1それぞれの決定に高々32ループ,実現可能かを調べるのに{ai}の長さループなので余裕です.

■コード
import java.util.*;
import java.lang.*;
import java.math.*;

public class AfraidOfEven{
public int[] restoreProgression(int[] seq){
int[] ret=new int[seq.length];
int[] arr=new int[seq.length];
String s1=null;
for(long a0=seq[0];a0<=Integer.MAX_VALUE;a0*=2){
arr[0]=(int)a0;
for(long a1=seq[1];a1<=Integer.MAX_VALUE;a1*=2){
arr[1]=(int)a1;
long d=a1-a0;
long a=a1+d;
boolean f=true;
for(int i=2;i<seq.length;i++){
arr[i]=(int)a;
if(a<0) f=false;
if(a%seq[i]!=0) f=false;
long k=a/seq[i];
if((k&(k-1))!=0) f=false;
a+=d;
}
if(f){
String s2=Arrays.toString(arr);
if(s1==null||s2.length()<s1.length()||(s2.length()==s1.length()&&s2.compareTo(s1)<0)){
System.arraycopy(arr,0,ret,0,seq.length);
s1=s2;
}
}
}
}
return ret;
}
}

0 件のコメント: