给你N*M个碎片,问能否用他们拼成一个矩形,矩形的边缘要全是F,除外界边缘的边要么是I,要么O,不能是F
1.碎片会重复出现,所以同样的碎片在同一个位置,如果已经不能放,直接跳过就行
2.矩形的边缘要全是F,除外界边缘的边要么是I,要么O,所以有I的数量等于0数量,上外边界F数量等于M,其他三边同理
WA了N遍
#include <stdio.h> #include<iostream> #include <string.h> #include<memory.h> using namespace std; int N; int M; int flag; int num[50]; char noPeat[50][4]; int nl = 0; char m[10][10][4]; int read() { char str[5]={0}; int IN[4] = { 0 }; int ON[4] = { 0 }; int FN[4] = { 0 }; gets(str); for(int i = 0; i < N * M; i++) { gets(str); int ok = 1; for(int j = 0; j < nl; j++) if(noPeat[j][0] == str[0] && noPeat[j][1] == str[1] && noPeat[j][2] == str[2] && noPeat[j][3] == str[3]) { ok = 0; num[j]++; break; } if(ok) { noPeat[nl][0] = str[0]; noPeat[nl][1] = str[1]; noPeat[nl][2] = str[2]; noPeat[nl][3] = str[3]; num[nl]++; nl++; } for(int j = 0; j < 4; j++) { if(str[j] == 'I') IN[j]++; if(str[j] == 'O') ON[j]++; if(str[j] == 'F') FN[j]++; } } if(FN[0] != M || FN[2] != M) return 0; if(FN[1] != N || FN[3] != N) return 0; if(IN[0] != ON[2] || IN[2] != ON[0]) return 0; if(IN[3] != ON[1] || IN[1] != ON[3]) return 0; return 1; } int check(int r, int c, char str[4]) { if(r == 1 && str[0] != 'F') return 0; if(r == N && str[2] != 'F') return 0; if(c == 1 && str[3] != 'F') return 0; if(c == M && str[1] != 'F') return 0; if(r != 1 && str[0] == 'F') return 0; if(r != N && str[2] == 'F') return 0; if(c != 1 && str[3] == 'F') return 0; if(c != M && str[1] == 'F') return 0; if(m[r][c - 1][1] == 'I' && str[3] != 'O') return 0; if(m[r][c - 1][1] == 'O' && str[3] != 'I') return 0; if(m[r - 1][c][2] == 'I' && str[0] != 'O') return 0; if(m[r - 1][c][2] == 'O' && str[0] != 'I') return 0; return 1; } void dfs(int r, int c) { if(c == M + 1) dfs(r + 1, 1); if(flag) return; if(r == N + 1) { flag = 1; return; } for(int i = 0; i < nl; i++) { if(num[i] && check(r, c, noPeat[i])) { num[i]--; m[r][c][0] = noPeat[i][0]; m[r][c][1] = noPeat[i][1]; m[r][c][2] = noPeat[i][2]; m[r][c][3] = noPeat[i][3]; dfs(r, c + 1); if(flag) return; m[r][c][0] = 0; m[r][c][1] = 0; m[r][c][2] = 0; m[r][c][3] = 0; num[i]++; } } } int main() { freopen("d://1.txt", "r", stdin); while (cin >> N >> M && (N + M)) { flag = 0; nl = 0; memset(num, 0, sizeof(num)); memset(m, 0, sizeof(m)); memset(noPeat, 0, sizeof(noPeat)); int ok = read(); if(!ok) { cout << "NO" << endl; continue; } dfs(1, 1); if(flag) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }