暴力枚举-POJ2965 The Pilots Brothers' refrigerator
2014-04-12 08:48
309 查看
题目大意:(直接说关键的了)一组4*4的开关,每次可以选择一个开关操作,操作时把它所在行及所在列的开关全部取反(包括它自己),问最少经过几次操作可以把开关全都打开(‘+’:关 ‘-’ :开),并给出操作的过程
这题和POJ1753是一样的,不过时间卡的特别紧,1753的代码改下交T掉了,没办法,逼着自己写位运算吧····
为了纪念我墨迹了好久,给代码加了注释
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <algorithm>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define ll long long
#define eps 1e-8
#define ms(x,y) (memset(x,y,sizeof(x)))
#define fr(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int maxn=65537;
int key;
int dir[16]={63624,62532,61986,61713,36744,20292,12066,7953,35064,17652,8946,4593,34959,17487,8751,4383};//翻转
int loc[16];//第i位是否为1
void init()
{
key=0;
fr(i,0,15)
{
char ch;
cin>>ch;
if(ch=='+')
key+=1;
key<<=1;
}
key>>=1;
loc[0]=1;
fr(i,1,15)
loc[i]=loc[i-1]<<1;
}
int num(int n)//返回操作需要的步骤数
{
int s=0;
fr(i,0,15)
{
if(n&loc[i])//判断当前位是否为1
s++;
}
return s;
}
void doit()
{
int ans=16,path=0;
fr(i,1,65535)//枚举路径
{
int k=key;
fr(j,0,15)
{
if(i&loc[j])
k^=dir[j];//翻转
}
if(!k)
{
int s=num(i);
if(ans>s)
{ans=s;path=i;}//如果答案比当前大 替换 并且记录路径
}
}
if(ans!=16)//特判16
{
cout<<ans<<endl;
int a[16];
ms(a,0);
fr(i,0,15)
{
if(path%2)a[i]=1;
path/=2;
}//把路径翻译出来
fr(i,0,15)
{
if(a[i])cout<<i/4+1<<' '<<i%4+1<<endl;
}
}
else
{
cout<<16<<endl;
fr(i,0,15)cout<<i/4+1<<' '<<i%4+1<<endl;
}
}
int main()
{
init();
doit();
}
这题和POJ1753是一样的,不过时间卡的特别紧,1753的代码改下交T掉了,没办法,逼着自己写位运算吧····
为了纪念我墨迹了好久,给代码加了注释
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <algorithm>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define ll long long
#define eps 1e-8
#define ms(x,y) (memset(x,y,sizeof(x)))
#define fr(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int maxn=65537;
int key;
int dir[16]={63624,62532,61986,61713,36744,20292,12066,7953,35064,17652,8946,4593,34959,17487,8751,4383};//翻转
int loc[16];//第i位是否为1
void init()
{
key=0;
fr(i,0,15)
{
char ch;
cin>>ch;
if(ch=='+')
key+=1;
key<<=1;
}
key>>=1;
loc[0]=1;
fr(i,1,15)
loc[i]=loc[i-1]<<1;
}
int num(int n)//返回操作需要的步骤数
{
int s=0;
fr(i,0,15)
{
if(n&loc[i])//判断当前位是否为1
s++;
}
return s;
}
void doit()
{
int ans=16,path=0;
fr(i,1,65535)//枚举路径
{
int k=key;
fr(j,0,15)
{
if(i&loc[j])
k^=dir[j];//翻转
}
if(!k)
{
int s=num(i);
if(ans>s)
{ans=s;path=i;}//如果答案比当前大 替换 并且记录路径
}
}
if(ans!=16)//特判16
{
cout<<ans<<endl;
int a[16];
ms(a,0);
fr(i,0,15)
{
if(path%2)a[i]=1;
path/=2;
}//把路径翻译出来
fr(i,0,15)
{
if(a[i])cout<<i/4+1<<' '<<i%4+1<<endl;
}
}
else
{
cout<<16<<endl;
fr(i,0,15)cout<<i/4+1<<' '<<i%4+1<<endl;
}
}
int main()
{
init();
doit();
}
相关文章推荐
- 【枚举】POJ1753 Flip Game&POJ2965 The Pilots Brothers' refrigerator
- [POJ2965]The Pilots Brothers' refrigerator【枚举】
- poj2965 The Pilots Brothers' refrigerator(直接计算或枚举Enum+dfs)
- POJ2965 The Pilots Brothers' refrigerator(枚举)
- 枚举 poj2965 The Pilots Brothers' refrigerator
- POJ 2965 The Pilots Brothers' refrigerator 枚举dfs
- POJ1965 The Pilots Brothers' refrigerator(dfs,回溯,枚举)
- poj 2965 The Pilots Brothers' refrigerator(dfs 枚举 +打印路径)
- POJ2965-The Pilots Brothers' refrigerator
- POJ 2965 The Pilots Brothers' refrigerator(枚举)
- poj2965-The Pilots Brothers' refrigerator
- poj2965 The Pilots Brothers' refrigerator(直接计算或枚举Enum+dfs)
- POJ2965《The Pilots Brothers' refrigerator》方法:DFS+Bit
- poj 2965 The Pilots Brothers' refrigerator 【dfs+枚举】【双十一大礼包】【刷题计划】
- poj 2965 The Pilots Brothers' refrigerator[ 枚举 ]
- POJ2965-The Pilots Brothers' refrigerator
- DFS.枚舉::poj1753 flip game && poj2965 the Pilots Brothers'refrigerator
- POJ2965 The Pilots Brothers' refrigerator dfs
- POJ 2965 The Pilots Brothers' refrigerator(暴力搜索)
- POJ1753 Flip Game & POJ2965 The Pilots Brothers' refrigerator (DFS)