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 down so 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.
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.
3 5 FOOF FOOI FOOI FOOI FFOI IOOF IOOI IOOI IOOI IFOI IOFF IOFI IOFI IOFI IFFI 0 0
YES题意:输入n,m。表示有一个n*m的拼图。然后输入每一块拼图F代表平的。I代表凸的。O代表凹的。要求判断这个拼图能不能拼出来。。
思路:深搜。。不过要进行剪枝不然会超时。一格格去放拼图。放不了就进行回溯。
剪枝点:
1、由于边缘一定是平的。内部一定是凸凹结合的。所以判断F的数量等不等于2 * n * m,以及I的数量等不等于O的数量。如果不等于直接输入NO结束。
2、如果有一块拼图在一个位置上不能拼。那么下次遇到一样的拼图的时候直接跳过(这个剪枝我剪了以后直接就过了..欣慰)
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int cmp(const void *a, const void *b) { return strcmp((char*)a + 1, (char*)b + 1); } int n, m; char d[5] = {"FIO"}; char dd[5] = {"FOI"}; char pin[40][10]; char map[10][10][10]; int vis[40]; int bian, in, on; int judge; int ju(int star, int x, int y) { if (pin[star][0] == 'F' && x != 1 || pin[star][1] == 'F' && y != m || pin[star][2] == 'F' && x != n || pin[star][3] == 'F' && y != 1) return 0; for (int i = 0; i < 3; i ++) { if ((pin[star][0] == d[i] && map[x - 1][y][2] != dd[i]) || (pin[star][3] == d[i] && map[x][y - 1][1] != dd[i])) return 0; } return 1; } void dfs(int x, int y) { if (x > n) { judge = 1; return; } if (y > m) { dfs(x + 1, 1); return; } char sb[5] = {"sbsb"}; for (int i = 0; i < n * m; i ++) { if (vis[i] == 0 && ju(i, x, y) && strcmp(sb, pin[i])) { strcpy(sb, pin[i]); strcpy(map[x][y], pin[i]); vis[i] = 1; dfs(x, y + 1); if(judge) return; vis[i] = 0; } } memset(map[x][y], 0, sizeof(map[x][y])); } int main() { while (scanf("%d%d%*c", &n, &m) != EOF && n + m) { judge = 0; in = 0; on = 0; bian = 0; memset(map, 0 , sizeof(map)); memset(vis, 0, sizeof(vis)); for (int i = 1; i <= m; i ++) { map[0][i][2] = 'F'; } for (int i = 1; i <= n; i ++) { map[i][0][1] = 'F'; } for (int i = 0; i < n * m; i ++) { gets(pin[i]); for (int j = 0; j < 4; j ++) { if (pin[i][j] == 'F') bian ++; if (pin[i][j] == 'I') in ++; if (pin[i][j] == 'O') on ++; } } if (bian != 2 * (n + m) || in != on) { printf("NO\n"); continue; } qsort(pin, n * m, sizeof(pin[0]), cmp); dfs(1, 1); if (judge) printf("YES\n"); else printf("NO\n"); } return 0; }