POJ 算法基础 Assignment: 编程作业—枚举 编程题#1: 画家问题
2015-09-16 19:55
330 查看
编程题#1: 画家问题
来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使。当他用画笔涂画第(i, j)个位置的砖时, 位置(i-1, j)、 (i+1, j)、 (i, j-1)、 (i, j+1)上的砖都会改变颜色。请你帮助Bob计算出最少需要涂画多少块砖,才能使所有砖的颜色都变成黄色。输入
第一行是个整数t(1≤t ≤20),表示要测试的案例数。然后是t个案例。每个案例的首行是一个整数n (1≤n ≤15),表示墙的大小。接下来的n行表示墙的初始状态。每一行包含n个字符。第i行的第j个字符表示位于位置(i,j)上的砖的颜色。“w”表示白砖,“y”表示黄砖。输出
每个案例输出一行。如果Bob能够将所有的砖都涂成黄色,则输出最少需要涂画的砖数,否则输出“inf”。样例输入
2 3 yyy yyy yyy 5 wwwww wwwww wwwww wwwww wwwww
样例输出
0 15
#include <iostream> #include <math.h> using namespace std; int guess(int *puzzle, int *press,int i) { int c, r, count = 0; for (c = 1; c < i+1; ++c) { if (press[(i+2)+c] == 1) count++; } for (r=1; r< i; r++) { for (c = 1; c < i+1; ++c) { // 跟踪puzzle第一行,计算press其他行的值 press[(r + 1)* (i+2) +c] = (puzzle[r*(i+2)+c] + press[r*(i+2)+c] + press[(r - 1)*(i+2)+c] + press[r*(i+2)+c - 1] + press[r*(i+2)+c + 1]) % 2; if (press[(r + 1)* (i+2) +c] == 1) count++; } } for (c=1; c < i + 1; c++) { if ((press[i*(i+2)+c - 1] + press[i*(i+2)+c] + press[i*(i+2)+c + 1] + press[(i - 1)*(i+2)+c]) % 2 != puzzle[i*(i + 2)+c]) { return -1; // 返回-1标示该press的第一行不能使地板全变黄 } } return count;//如果能使地板全变黄,返回该办法所需涂的地砖的个数 } int enumerate (int *puzzle, int *press,int i) { int c, sum = -1,n= (int)pow(2,i); for ( c=1; c<i+1; c++) { press[(i+2)+c] = 0; } if (guess(puzzle, press, i) != -1) { sum = guess(puzzle, press, i); } while (n--) { press[(i+2)+1]++; c = 1; while (press[(i+2)+c] > 1) { press[(i+2)+c] = 0; c++; press[(i+2)+c]++; } if (guess(puzzle, press, i) != -1) { if (sum == -1) { sum = guess(puzzle, press, i); } else if (guess(puzzle, press, i) < sum) { sum = guess(puzzle, press, i); } } } return sum; } int main() { int cases,i; cin>>cases; while (cases--) { cin>>i; if (i == 1) { char t; cin >> t; if (t == 'w') { cout<<1<<endl; } else { cout<<0<<endl; } } else { int *puzzle, *press; puzzle = new int[(i+2)*(i+2)];//初始数组 press = new int[(i+2)*(i+2)];//按下状态,按下为1,未操作为0 //初始化press数组 int c, r; for (r=0; r<i+1; r++) { press[r*(i+2)] = press[r*(i+2)+i+1] = 0; } for (c=1; c<i+1; c++) { press[c] = 0; } //输入数据 for(r=1; r<i+1; r++) { for(c=1; c<i+1; c++) { char t; cin >> t; if (t == 'w') { puzzle[r*(i+2)+c] = 1; } else { puzzle[r*(i+2)+c] = 0; } } } int result = enumerate(puzzle,press,i); if (result == -1) { cout<<"inf"<<endl; } else { cout<<result<<endl; } } } return 0; }
相关文章推荐
- 酷壳陈皓:如何学好C++语言
- java线程的同步方式
- c++异或运算
- 替换字符串中空格算法
- C++技术点积累(4)——继承、多态、抽象类
- C++技术点积累(3)——对象初始化列表、运算符重载
- asp.net 执行Response.Write后页面变形
- 纯代码实现QQ聊天界面---TableView使用详解
- php将xml文件中的查询具体节点名字下的值
- java SE复习笔记10
- Ubuntu 下如何设置 Java 环境变量
- matlab安装问题
- QT5开发及实例1 计算圆周面积 之新建项目文件
- 单例模式C++实现
- Java 模版方法(Template Method)
- SpringMVC部署步骤
- c++find函数用法
- 1.2 Implement a function void reverse(char* str) in C or C++ which reverses a nullterminated string.
- asp.net将sql语句封装在类库中
- 对“demo!demo.Index+HookProc::Invoke”垃圾收集的类型已委托回调。这可能会导致应用程序崩溃、损坏和数据丢失。当传递委托给非托管代码,托管应用程序必须让这些委托保持活着