uva 519 Puzzle (II)(回溯)
2015-02-10 19:29
316 查看
uva 519 Puzzle (II)
Little Barborka has just started to learn how to solve a picture puzzle. She has started with a small one containing 15 pieces. Her daddy tries to solve the puzzle too. To make it a little bit harder for himself, he has turned all puzzle pieces upside downso that he cannot see pictures on the pieces. Now he is looking for a solution of the puzzle. Normally the solution should exist but he is not sure whether Barborka has not replaced some pieces of the puzzle by pieces of another similar puzzle. Help him and
write a program which reads a description of a set of puzzle pieces and decides whether it is possible to assembly the pieces into a rectangle with given side lengths or not.
Input
The input file consists of blocks of lines. Each block except the last describes one puzzle problem. In the first line of the block there are integersn and m,
separated by one space. The integers
n, m indicate the number of rows and columns in the puzzle respectively. The description of individual puzzle pieces is in the following
lines of the block. Each piece is a rectangle 3 centimeters wide and 4 centimeters high with possible juts or cavities in the middle
of its sides. For each side of a puzzle piece just one of the following possibilities is true (see picture):
there is no jut or cavity on the side, i.e., the side is flat - such sides can be used only on edges of the final picture when assembling the puzzle,
there is one jut in the middle of the side,
there is one cavity in the middle of the side.
As is usual, two pieces can be placed side by side only if one has a jut and the other has a cavity on corresponding sides. We will denote the flat sides by
F, the sides with juts by O and the sides with cavities by
I. Each piece is described by four letters characterizing its top, right, bottom, and left side. To make the task easier the pieces can be used only as they are described i.e. they cannot be turned.
After each block there is an empty line. The last block consists of just one line containing 0 0, i.e. two zeros separated by one space.
Output
The output file contains the lines corresponding to the blocks in the input file. A line containsYES if the corresponding block in the input file describes a puzzle that can be correctly assembled. Otherwise it contains
NO. There is no line in the output file corresponding to the last ``null'' block of the input file.
Sample Input
3 5 FOOF FOOI FOOI FOOI FFOI IOOF IOOI IOOI IOOI IFOI IOFF IOFI IOFI IOFI IFFI 0 0
Sample Output
YES
题目大意:给出一些拼图的碎片,要求判断是否能组成一个矩形,对于碎片,F表示平面,I表示凸面,O表示凹面,对于矩形,边必须为平, 并且碎片相连这能是以IO形式。
解题思路:
1)IO也就是突出和凹陷的数量要相等,F要等于长加上宽的和乘以二,这两条不满足直接pass。
2)获取数据之后要预处理:按照字典序排列,会简化后面回溯的搜索。)
3)根据上方和左侧的拼图推出当前拼图(如果有的话)。
4)如果之前的相同的拼图不符合要求,则接下来相同的拼图都可以直接跳过(需要排序)。
#include<stdio.h> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; int n, m, vis[40]; char p[40][5], gra[6][6][5]; int cmp(const void *a, const void *b) { return strcmp((char*)a, (char*)b); } int check(int x, int y, int i) { if (x == 0 && p[i][0] != 'F') return 0; //在第一行,top不为F if (y == m - 1 && p[i][1] != 'F') return 0; //在最后一列,right不为F if (x == n - 1 && p[i][2] != 'F') return 0; //在最后一行,bottom不为F if (y == 0 && p[i][3] != 'F') return 0; //在第一列,left不为F if (x != 0 && p[i][0] + gra[x - 1][y][2] != 'I' + 'O') return 0; //与上方拼图不对应 if (y != 0 && p[i][3] + gra[x][y - 1][1] != 'I' + 'O') return 0; //与左边拼图不对应 return 1; } int DFS(int x, int y, int d) { if (d == n * m) return 1; char temp[5] = {0}; for (int i = 0; i < n * m; i++) { if (!vis[i] && strcmp(temp, p[i]) && check(x, y, i)) { //该拼图没被使用过,若跟前一个拼图相同且前一个拼图无法使用则跳过该拼图,检查当前拼图是否符合条件 strcpy(temp, p[i]); strcpy(gra[x][y], p[i]); vis[i] = 1; if (DFS((d + 1) / m, (d + 1) % m, d + 1)) return 1; vis[i] = 0; } } return 0; } int main() { while (scanf("%d %d", &n, &m) == 2, (n || m)) { int count[200] = {0}; memset(vis, 0, sizeof(vis)); memset(p, 0, sizeof(p)); memset(gra, 0, sizeof(gra)); for (int i = 0; i < n * m; i++) { scanf("%s", p[i]); for (int j = 0; j < 4; j++) { count[p[i][j]]++; } } qsort(p, n * m, sizeof(p[0]), cmp); if (count['F'] != 2 * (n + m) || count['I'] != count ['O']) { printf("NO\n"); continue; } if (DFS(0, 0, 0)) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- UVA - 519 Puzzle (II)(回溯+剪枝)
- uva 519 Puzzle (II)(回溯)
- UVA - 519 Puzzle (II) 回溯+剪枝
- uva519 - Puzzle (II)(回溯)
- uva 519 Puzzle (II)
- UVa 519 - Puzzle (II)
- uva519 Puzzle (II)
- UVA 519 Puzzle (II)
- UVA 519 Puzzle (II)
- UVA 519 Puzzle (II) (dfs + 剪枝)
- UVA - 519 Puzzle (II)
- uva 519(回溯)
- UVa-227 - Puzzle
- UVA - 10132 File Fragmentation 暴力+回溯
- UVA - 165 Stamps 回溯
- uva live 12846 A Daisy Puzzle Game
- 【Uva 227】 Puzzle
- UVa 11426 GCD - Extreme (II) / 素数筛选 + 欧拉函数
- UVA227 Puzzle
- UVa 227 Puzzle