zoukankan      html  css  js  c++  java
  • POJ 3279 Fliptile.cpp

    Description:

    有一个n*m的格子,每个格子都有黑白两面(0表示白色,1表示黑色)。我们需要把所有的格子都反转成黑色,每反转一个格子,它上下左右的格子都会跟着反转。请求出用最小步数完成反转时每个格子反转的次数。有多个解时,输出字典序最小的一组。

    Analysis:

    一个格子没有必要翻转两次。
    如果第一行翻转方法确定了,那么递推下面所有行就都确定了。
    先确定第一行翻转方法O(2^n),接下来每一行,如果某一个格子的上一行格子是黑色的,那么就翻转这个格子。
    时间复杂度O(nm2^n)

    Code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define White 0
    #define Black 1
    using namespace std;
    const int N = 20;
    const int dx[5] = {-1,0,0,0,1};
    const int dy[5] = {0,-1,0,1,0};
    int tile[N][N],flip[N][N],opt[N][N];
    int m,n;
    int getColour(int x,int y)
    {
    	int c = tile[x][y];
    	for(int d = 0;d < 5;++d)
    	{
    		int x1 = x + dx[d],y1 = y + dy[d];
    		if((0 <= x1 && x1 < m) && (0 <= y1 && y1 < n))
    		{
    			c += flip[x1][y1];
    		}
    	}
    	return c % 2;
    }
    int calc()
    {
    	for(int i = 1;i < m;++i)
    	{
    		for(int j = 0;j < n;++j)
    		{
    			if(getColour(i-1,j) == Black)
    			{
    				flip[i][j] = 1;
    			}
    		}
    	}
    	for(int i = 0;i < n;++i)
    	{
    		if(getColour(m - 1,i) == Black)
    		{
    			return -1;
    		}
    	}
    	int ans = 0;
    	for(int i = 0;i < m;++i)
    	{
    		for(int j = 0;j < n;++j)
    		{
    			ans += flip[i][j];
    		}
    	}
    	return ans;
    }
    void solve()
    {
    	int ans = 10000;
    	int flag = 1;
    	for(int i = 0;i < (1 << n);++i)
    	{
    		memset(flip,0,sizeof(flip));
    		for(int j = 0;j < n;++j)
    		{
    			flip[0][n - j - 1] = (i >> j) & 1;
    		}
    		int num = calc();
    		if(num < ans && num > 0)
    		{
    			ans = num;
    			flag = 0;
    			memcpy(opt,flip,sizeof(flip));
    		}
    	}
    	if(flag)
    	{
    		printf("IMPOSSIBLE
    ");
    	}
    	else{
    		for(int i = 0;i < m;++i)
    		{
    			for(int j = 0;j < n;++j)
    			{
    				printf("%d%c",opt[i][j],j + 1 == n ? '
    ' : ' ');
    			}
    		}
    	}
    }
    int main()
    {
    	scanf("%d%d",&m,&n);
    	for(int i = 0;i < m;++i)
    	{
    		for(int j = 0;j < n;++j)
    		{
    			scanf("%d",&tile[i][j]);
    		}
    	}
    	solve();
    	return 0;
    }
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    若依ruoyi summernote 富文本提交数据 部分代码被过滤 修改xss配置可忽略过滤
    java中Map实现1对多
    Windows()64位)下Redis的安装使用
    SpringMvc java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
    字符替换
    oracle null 空值排序- NVL,COALESCE , GREATEST ,LEAST
    oracle 日期,时间函数 date,to_date,extract,to_timestamp,last_day,frist_day
    获取树形数据(区域,父子级关系的树形数据)
    git的操作
    MySQL数据库之MyISAM与InnoDB的区别
  • 原文地址:https://www.cnblogs.com/Zforw/p/11178202.html
Copyright © 2011-2022 走看看