POJ 1753题解

题意简述

 

              题目给出一个4X4棋盘(黑白两色),要求求出使棋盘成为一种颜色最少的翻转次数;如bwwb bbwb bwwb bwww需要四次翻转到白色.

 

算法分析

 

     第一行开,要始翻转棋子的颜色,又不会造成此行混乱(即影响旁边的棋子),只能翻转其正下方的棋子。这样就出现个问题,就是正向的话第一行,永远不会翻转。反向的话最后一行永远不会翻转。(就会造成需要写两个方向的函数)同时不动第一行和最后一行,还有个问题 就是如果四个角翻转可以的话,是必须单独判断的,不然得不到正确答案。当然这个算法是就这个题的,其实很有问题。。。应该用一种可行通用算法来解决,后面会说

 

程序样例

#include <stdio.h>

unsigned short OneColor(char a[][4],unsigned short c)
{
	unsigned short i,j,counter=0;
	if(c == 1)//to white
	{
		if(a[0][0] ==0 && a[0][1] == 0 &&  a[1][0] == 0)
		{
			++counter;
			a[0][0]=a[0][1]=a[1][0]=1;
		}
		if(a[0][2] ==0 && a[0][3] ==0 && a[1][3] == 0)
		{
			++counter;
			a[0][2] = a[0][3] = a[1][3]=1;
		}
		if(a[3][0] == 0 && a[3][1] ==0 && a[2][0] == 0)
		{
			++counter;
			a[3][0] = a[3][1] = a[2][0]=1;
		}
		if(a[3][3] == 0 && a[2][3] == 0 && a[3][2] == 0)
		{
			++counter;
			a[3][3] = a[2][3] = a[3][2]=1;
		}
		for(i=0;i<3;++i)
		{
			for(j=0;j<4;++j)
			{
				if(a[i][j] != 1)
				{
					++counter;
					++i;
					a[i][j]^=1;
					a[i-1][j]^=1;
					if(j > 0)
						a[i][j-1]^=1;
					if(i < 3)
						a[i+1][j]^=1;
					if(j < 3)
						a[i][j+1]^=1;
					--i;
				}
			}
		}
		if(a[3][0] != 1 || a[3][1] != 1 || a[3][2] != 1 || a[3][3] != 1)
			counter=20;
	}else//to black
	{
		if(a[0][0] ==1 && a[0][1] ==1 && a[1][0] == 1)
		{
			++counter;
			a[0][0]=a[0][1]=a[1][0]=0;
		}
		if(a[0][2] ==1 && a[0][3] ==1 && a[1][3] == 1)
		{
			++counter;
			a[0][2] = a[0][3] = a[1][3]=0;
		}
		if(a[3][0] ==1 && a[3][1] ==1 && a[2][0] == 1)
		{
			++counter;
			a[3][0] = a[3][1] = a[2][0]=0;
		}
		if(a[3][3] ==1 && a[2][3] ==1 && a[3][2] == 1)
		{
			++counter;
			a[3][3] = a[2][3] = a[3][2]=0;
		}
		for(i=0;i<3;++i)
		{
			for(j=0;j<4;++j)
			{
				if(a[i][j] != 0)
				{
					++counter;
					++i;
					a[i][j]^=1;
					a[i-1][j]^=0;
					if(j > 0)
						a[i][j-1]^=1;
					if(i < 3)
						a[i+1][j]^=1;
					if(j < 3)
						a[i][j+1]^=1;
					--i;
				}
			}
		}
		if(a[3][0] != 0 || a[3][1] != 0 || a[3][2] != 0 || a[3][3] != 0)
			counter=20;
	}
	return counter;
}

unsigned short OneColorn(char a[][4],unsigned short c)
{
	unsigned short i,j,counter=0;
	if(c == 1)//to white
	{
		if(a[0][0] ==0 && a[0][1] == 0 &&  a[1][0] == 0)
		{
			++counter;
			a[0][0]=a[0][1]=a[1][0]=1;
		}
		if(a[0][2] ==0 && a[0][3] ==0 && a[1][3] == 0)
		{
			++counter;
			a[0][2] = a[0][3] = a[1][3]=1;
		}
		if(a[3][0] == 0 && a[3][1] ==0 && a[2][0] == 0)
		{
			++counter;
			a[3][0] = a[3][1] = a[2][0]=1;
		}
		if(a[3][3] == 0 && a[2][3] == 0 && a[3][2] == 0)
		{
			++counter;
			a[3][3] = a[2][3] = a[3][2]=1;
		}
		for(i=3;i!=0;--i)
		{
			for(j=0;j<4;++j)
			{
				if(a[i][j] != 1)
				{
					++counter;
					--i;
					a[i][j]^=1;
					if(i > 0)
						a[i-1][j]^=1;
					if(j > 0)
						a[i][j-1]^=1;
					a[i+1][j]^=1;
					if(j < 3)
						a[i][j+1]^=1;
					++i;
				}
			}
		}
	if(a[0][0] != 1 || a[0][1] != 1 || a[0][2] != 1 || a[0][3] != 1)
			counter=20;
	}else//to black
	{
		if(a[0][0] ==1 && a[0][1] ==1 && a[1][0] == 1)
		{
			++counter;
			a[0][0]=a[0][1]=a[1][0]=0;
		}
		if(a[0][2] ==1 && a[0][3] ==1 && a[1][3] == 1)
		{
			++counter;
			a[0][2] = a[0][3] = a[1][3]=0;
		}
		if(a[3][0] ==1 && a[3][1] ==1 && a[2][0] == 1)
		{
			++counter;
			a[3][0] = a[3][1] = a[2][0]=0;
		}
		if(a[3][3] ==1 && a[2][3] ==1 && a[3][2] == 1)
		{
			++counter;
			a[3][3] = a[2][3] = a[3][2]=0;
		}
		for(i=3;i!=0;--i)
		{
			for(j=0;j<4;++j)
			{
				if(a[i][j] != 0)
				{
					++counter;
					--i;
					a[i][j]^=1;
					if(i > 0)
						a[i-1][j]^=1;
					if(j > 0)
						a[i][j-1]^=1;
					a[i+1][j]^=1;
					if(j < 3)
						a[i][j+1]^=1;
					++i;
				}
			}
		}
	if(a[0][0] != 0 || a[0][1] != 0 || a[0][2] != 0 || a[0][3] != 0)
			counter=20;
	}
	return counter;
}

int main()  
{  
    char a[4][4],b[4][4],c[4][4],d[4][4];//b==0 w==1
	char ch;
	unsigned short i,j;
	for(j=0;j<4;++j)
	{
		for(i=0;i<4;++i)
		{
			scanf("%c",&ch);
			if(ch == 'w')
			{
				a[j][i]=1;
				b[j][i]=1;
				c[j][i]=1;
				d[j][i]=1;
			}else
			{
				a[j][i]=0;		
				b[j][i]=0;
				c[j][i]=0;		
				d[j][i]=0;
			}		
		}
		scanf("%c",&ch);
	}
	i=OneColor(a,1);
	ch=OneColorn(b,1);
	if(ch < i)
		i=ch;
	j=OneColor(c,0);
	ch=OneColorn(d,0);
	if(ch < j)
		j=ch;
	if(i < j)
		j=i;
	if(j == 20)
		printf("Impossible\n");
	else
		printf("%u\n",j);
}

  四个数组来存原始数据,分别从上到下(两次,一黑一白),从下到上(两次),最小的当作答案。

 

指标:

  POJ评定  164K 0MS

 

思考:

  无疑,这样的代码很冗杂,也很不好看,百度一下。用DFS+枚举(BFS也可以)来完成很方便,代码也很精炼~

  参考:http://www.lvzejun.cn/?p=332

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值