■問題
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 件のコメント:
コメントを投稿