POJ 1753题解

来源:互联网 发布:java基础课程 精易 编辑:程序博客网 时间:2024/05/22 04:52

题意简述

 

              题目给出一个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==1char 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");elseprintf("%u\n",j);}

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

 

指标:

  POJ评定  164K 0MS

 

思考:

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

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

  

原创粉丝点击