■1201 Lattice Practices
まず,10枚の板から5枚を選び,その5枚で構成出来るパターンを全て列挙.列挙の際,反転させても変わらない板がある場合があるので,重複を考慮する必要がある.それぞれのパターンに対応するパターンを残りの5枚で構成できうるかを判定する. 10個から5個選ぶ…10P5=30240 反転の種類…25=32import java.util.*; import java.lang.*; import java.math.*; import java.io.*; import static java.lang.Math.*; import static java.util.Arrays.*; public class Main{ Scanner sc=new Scanner(System.in); int INF=1<<28; double EPS=1e-9; int[] a, rev; int n, m; void run(){ n=10; m=n/2; a=new int[n]; rev=new int[1<<m]; for(int i=0; i<1<<m; i++){ int x=i; x=(x&0x55555555)<<1|(x>>1)&0x55555555; x=(x&0x33333333)<<2|(x>>2)&0x33333333; x=(x&0x0f0f0f0f)<<4|(x>>4)&0x0f0f0f0f; x=(x<<24)|((x&0xff00)<<8)|((x>>8)&0xff00)|(x>>24); rev[i]=(int)(x>>(32-m))&((1<<m)-1); } for(;;){ for(int i=0; i<n; i++){ String s=sc.next(); if(s.equals("END")){ return; } a[i]=Integer.parseInt(s, 2); } solve(); } } void solve(){ int ans=0; int[] b=new int[m]; int[] c=new int[m]; int comb=(1<<m)-1; boolean[] used=new boolean[m]; for(; comb<1<<n;){ // 2^(反転させても同じものの個数)で割る int div=1; for(int i=0, j=0, k=0; k<10; k++){ if((comb>>k&1)==1){ b[i++]=a[k]; if(rev[a[k]]==a[k]){ div*=2; } }else{ c[j++]=a[k]; } } Arrays.sort(b); int sum=0; for(;;){ // 2^n通り反転させる for(int sup=0; sup<1<<m; sup++){ for(int i=0; i<m; i++){ if((sup>>i&1)==1){ b[i]=rev[b[i]]; } } // bの並びをcで構築できるか Arrays.fill(used, false); sum++; for(int i=0; i<m; i++){ int bits=0; for(int j=0; j<m; j++){ bits=(bits<<1)|(b[j]>>i&1); } int k=-1; for(int j=0; j<m; j++){ if(!used[j] &&((c[j]^bits)==(1<<m)-1||(rev[c[j]]^bits)==(1<<m)-1)){ k=j; } } if(k>=0){ used[k]=true; }else{ sum--; break; } } for(int i=0; i<m; i++){ if((sup>>i&1)==1){ b[i]=rev[b[i]]; } } } if(!nextPermutation(b)){ break; } } ans+=sum/div; int x=comb&-comb, y=comb+x; comb=((comb&~y)/x>>1)|y; } ans/=8; // 鏡像反転*回転 println(""+ans); } boolean nextPermutation(int[] is){ int n=is.length; for(int i=n-1; i>0; i--){ if(is[i-1]<is[i]){ int j=n; while(is[i-1]>=is[--j]); swap(is, i-1, j); rev(is, i, n); return true; } } rev(is, 0, n); return false; } void swap(int[] is, int i, int j){ int t=is[i]; is[i]=is[j]; is[j]=t; } void rev(int[] is, int i, int j){ for(j--; i<j; i++, j--){ int t=is[i]; is[i]=is[j]; is[j]=t; } } void debug(Object... os){ System.err.println(Arrays.deepToString(os)); } void print(String s){ System.out.print(s); } void println(String s){ System.out.println(s); } public static void main(String[] args){ // System.setOut(new PrintStream(new BufferedOutputStream(System.out))); new Main().run(); } }
0 件のコメント:
コメントを投稿