您的位置:首页 > 其它

poj 1753 filp game 2015年暑假训练第一题 枚举

2015-06-30 14:28 337 查看
题意就是说:翻牌,随便翻到一张牌,其上下左右随他都得翻,看最少用翻几张牌,能够让16张牌全为正或全为负。

这道题有一个大坑,就是每一张牌其实只能翻奇数次,比如翻的顺序为 (3,2)-> (2,2) -> (3,2) = = (2,2) 是 等价的

故最多翻的个数是16,从0到16一个一个测试,枚举的是翻牌的个数,若全为正或反,则断开枚举,否则一直枚举

最多有C(0,16)+C(1,16)+。。。+C(16,16)=2^16次,

这道题首先是用dfs码的,但是最麻烦的情况下会超时吧,比如Impossible;//不会改,我只是一名小牛

后来用枚举翻牌个数打的,期间遇到很多问题;

1:二维变一维,在翻牌时要注意关联牌的翻转;

2:一般组合代码的实现,即16个牌中抽n个牌的代码n>=0,n<=16;

3: 翻牌后若不为全,还得翻回来;//其实可以把实参数组传递给形参解决;

一般组合组合的代码如下:省略打的

int n,m;
cin>>n>>m;
int rcd[10];
int num[10];
void select_combination(int l,int p)
{
int i;
if(l==m)
{
for(i=0;i<m;i++)
{
cout<<rcd[i];
if(i<m-1)
cout<<' ';
}
cout<<endl;
return ;
}
for(i=p;i<n;i++)
{
rcd[l]=num[i];
select_combination(int l+1,int i+1)
}
}
int mian()
{
select_combination(0,0);
return 0;
}


下面是我打的代码:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
char a[5][5];//二维
char own[30];//一维
int add[6]= {0,4,-4,1,-1};//翻转区域
//queue<int> s;
int num[30];
int point;//
int k=0;
int n=16;
int find()//发现是否出现全为0或全为1
{
int i;
int k1=1,k2=1;
for(i=0; i<16; i++) //判断是否全为黑色
{
if(own[i]=='0')//有白色
{
k1=0;
}
if(own[i]=='1')//有黑色
{
k2=0;
}
}
if(k1==0&&k2==0)//既有白,又有黑
{
return -1;
}
else
return 0;//全
}
int tell(int i)//判断是否出界
{
if(i<0||i>=16)
return 0;
else
return 1;
}
void fanzhuan(int k)//进行翻转
{
int p;
int i;
for(i=0; i<3; i++)
{
p=k+add[i];
if(tell(p)==1)
{
if(own[p]=='1')
own[p]='0';
else
own[p]='1';
}
}
int x=k%4;
if(x==0)
{
p=k+1;
if(tell(p)==1)
{
if(own[p]=='1')
own[p]='0';
else
own[p]='1';
}
}
else if(x==3)
{
p=k-1;
if(tell(p)==1)
{
if(own[p]=='1')
own[p]='0';
else
own[p]='1';
}
}
else
{
for(i=3;i<5;i++)
{
p=k+add[i];
if(tell(p)==1)
{
if(own[p]=='1')
own[p]='0';
else
own[p]='1';
}
}

}
}
int panduan()
{
int i,j;
for(i=0; i<point; i++)
{
int p=num[i];
fanzhuan(num[i]);
}
if(find()==0)//全
return 1;
else
return 0;
}
void  select_com(int l,int p)
{
int i;
if(l==point)
{
int g=panduan();
if(g==1)
{
k=1;
cout<<point<<endl;
return ;
}
else
{
int t=panduan();
}
}
for(i=p; i<n; i++)
{
if(k==0)
{
num[l]=i;
select_com(l+1,i+1);
}
}
}
int main()
{
while(cin>>a[0][0])
{
int i,j;
int start=0;
for(i=1; i<=3; i++)
{
cin>>a[0][i];
}
for(i=0; i<4; i++)
{
if(a[0][i]=='b')
a[0][i]='1';
else
a[0][i]='0';
own[start++]=a[0][i];
}
for(i=1; i<=3; i++)
{
for(j=0; j<4; j++)
{
cin>>a[i][j];
if(a[i][j]=='b')//黑色
a[i][j]='1';
else//白色
a[i][j]='0';
own[start++]=a[i][j];//二维变一维
}
}
int m=1;
if(find()==0)
cout<<0<<endl;
else//枚举翻转个数m
{
while(m<16)
{
point=m;
select_com(0,0);
if(k==1)
break;
m++;
}
if(k==0)
cout<<"Impossible"<<endl;
}
k=0;
}
return 0;
}


测试案例如下:

代码已AC

bwbw

wwww

bbwb

bwwb

Impossible

bwwb

bbwb

bwwb

bwww

4

wwww

wwww

wwww

wwww

0

bbbb

bbbb

bbbb

bbbb

0

bbbb

bwbb

bbbb

bbbb

Impossible

bwbb

bwbb

bwbb

bbbb

Impossible

bwbb

wwwb

bwbb

bbbb

1

wwww

wwwb

wwbb

wwwb

1

wwww

wwww

wwwb

wwbb

1

wbwb

bwbw

wbwb

bwbw

Impossible

bbbb

bwwb

bwwb

bbbb

4

bwwb

wbbw

wbbw

bwwb

4

bbww

bbww

wwbb

wwbb

Impossible

bbwb

bbbw

wwbb

wwwb

Impossible

wwwb

wwbw

wbww

wwbw

Impossible

bbbb

wwww

wwbb

wbbb

Impossible

bwwb

wbwb

wbbb

wbbb

4

bwbb

bwbb

bwbw

bbbw

5

wbwb

bbbb

bbww

wbbb

6

bbwb

bbbb

wbwb

bbbb

5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: