您的位置:首页 > 其它

poj1222 枚举 和 高斯消元

2014-04-14 13:59 357 查看
接触开关问题,最先的方法是枚举。然后接触到了更加高深的高斯消元。

高斯消元的思想:把一个全部熄灭的矩阵经过一系列开关后得到初始的状态。

具体分析可参照 http://blog.csdn.net/shiren_Bod/article/details/5766907

下面附上的代码付注释:

#include <iostream>
using namespace std;
int map[31][31];
void gauss()
{
const int  equ=30,var=30;
int h=0,col=0;
for(;h<equ&&col<var;col++)
{
int k=h;
for(;k<equ;k++)
if(map[k][col])
break;
if(map[k][col])
{
for(int i=0;i<=var;i++)
swap(map[k][i],map[h][i]);
for(int i=0;i<equ;i++)
if(i!=h&&map[i][col])
for(int k=0;k<=var;k++)
map[i][k]^=map[h][k];
h++;
}
}
}
int main()
{
int cas;
cin>>cas;
for(int l=1;l<=cas;l++)
{
memset(map,0,sizeof(map));
for(int i=0;i<30;i++)
cin>>map[i][30];
for(int i=0;i<30;i++)
{
map[i][i]=1;
if(i%6!=0)
map[i-1][i]=1;
if(i%6!=5)
map[i+1][i]=1;
if(i<24)
map[i+6][i]=1;
if(i>=6)
map[i-6][i]=1;
}
gauss();
cout<<"PUZZLE #"<<l<<endl;
for(int i=0;i<30;i++)
{
cout<<map[i][30]<<" ";
if((i+1)%6==0)
cout<<endl;
}
}
return 0;
}


枚举代码:

#include <iostream>
#include <algorithm>
using namespace std;
int map[5][6],f[5][6],ans[5][6];
int dx[]={-1,0,0,0,1};
int dy[]={0,-1,0,1,0};
int maxn=1000;
bool ok(int a,int b)
{
int sum=map[a][b];
for(int i=0;i<5;i++)
{
int x=a+dx[i];
int y=b+dy[i];
if(x>=0&&x<5&&y>=0&&y<6)
sum+=f[x][y];
}
return sum%2==1;
}
void solve()
{
for(int i=1;i<5;i++)
for(int j=0;j<6;j++)
if(ok(i-1,j))
f[i][j]=1;
for(int i=0;i<6;i++)
if(ok(4,i))
return ;
int sum=0;
for(int i=0;i<5;i++)
for(int j=0;j<6;j++)
sum+=f[i][j];
if(sum<maxn)
{
memcpy(ans,f,sizeof(f));
maxn=sum;
}
}
int main()
{
int cas;
cin>>cas;
for(int k=1;k<=cas;k++)
{
maxn=1000000;
for(int i=0;i<5;i++)            //1代表开灯。
for(int j=0;j<6;j++)
{
int a;
cin>>a;
map[i][j]=a;
}
for(int i=0;i< 1<<6;i++)
{
memset(f,0,sizeof(f));
for(int j=0;j<6;j++)
f[0][j]=(i>>j)&1;
solve();
}
cout<<"PUZZLE #"<<k<<endl;
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
cout<<ans[i][j]<<' ';
cout<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: