zoukankan      html  css  js  c++  java
  • POJ3279(开关后续)

    描述:
    一个(n*m的矩阵,每个格子有0和1两种状态.每次可以翻一个格子,并且此格子的上下左右都要被翻。)
    (目标状态应该全为0,求最少翻的次数,输出最小字典序的方案)

    这儿可就麻烦了啊,开关从一维变到了二维,不能通过确定左上角的状态往后递推

    但是,我们可以枚举第一行的状态,第二行怎么翻就确定了,因为此时上面的格子只有下面的格子可以改变

    Ⅰ.枚举和预处理

    关于枚举第一行,可以用二进制数很方便的表示出来

    同样f[i][j]表示(i,j)位置有没有被翻过,那我们统计一下上下左右被翻的次数就可以的得知此时状态

    最后,判断第N行是否全为0即可。

    #include <cstring>
    #include <iostream>
    using namespace std;
    const int inf=1<<29;
    int n,m,ans,a[20][20],f[20][20],s[20][20];
    int b[5]={0,0,1,-1},c[5]={1,-1,0,0};
    bool isfilp(int x,int y)
    {
    	int k=f[x][y]+a[x][y];//统计被翻过的次数 
    	for(int i=0;i<4;i++)
    	{
    		int nx=x+b[i],ny=y+c[i];
    		if(nx<1||ny<1||nx>n||ny>m)	continue;
    		k+=f[nx][ny];
    	}
    	return k%2; 
    }
    int cal()
    {
    	int ans=0;
    	for(int i=2;i<=n;i++)
    	for(int j=1;j<=m;j++)
    		if(isfilp(i-1,j))//如果需要翻转
    		f[i][j]=1;
    	for(int i=1;i<=m;i++)	
    	if(isfilp(n,i))	return -1;//最后一行还要被翻,显然不可行 
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=m;j++)
    	ans+=f[i][j];
    	return ans;
    }
    int main()
    {
    	while(cin>>n>>m)
    	{
    		ans=inf;
    		for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		cin>>a[i][j];
    		int last=1<<m;
    		for(int i=0;i<last;i++)
    		{
    			memset(f,0,sizeof(f));
    			for(int j=1;j<=m;j++)
    				if(i&(1<<(j-1)))
    					f[1][j]=1;//初始化第1行
    			int val=cal();
    			if(val==-1)	continue;
    			if(val<ans) 
    			{
    				ans=val;
    				memcpy(s,f,sizeof(f));//把方案保存下来 
    			}
    		}
    		if(ans==inf)	cout<<"IMPOSSIBLE"<<endl;
    		else
    		{
    			for(int i=1;i<=n;i++)
    			{
    				for(int j=1;j<=m;j++)
    					cout<<s[i][j]<<" ";
    				cout<<endl;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    JDBC获取数据库表字段信息
    No bean named 'springSecurityFilterChain' is defined
    VS 2010中对WPF4有哪些多点触摸支持?
    文件管理File类
    VS 2010 Beta2中WPF有哪些改进?
    WPF的实质
    C#中AppDomain.CurrentDomain.BaseDirectory与Application.StartupPath的区别
    VS 2010 Beta2中WPF与Silverlight的关键区别?
    C# 图片与byte[]之间以及byte[]与string之间的转换
    日期格式化{0:yyyyMMdd HH:mm:ss.fff}和{0:yyyyMMdd hh:mm:ss.fff}的区别
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12606269.html
Copyright © 2011-2022 走看看