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