一道考数据结构的好题
要利用好斜坐标系来表示各点,原理网上都有
题目连接。。。
自己闲着无聊用冗杂的代码压时间,居然压到32ms
#include <iostream> #include <algorithm> using namespace std; #define CHOICE_R 0 #define CHOICE_C 1 int side_len, triangle_num, triangle[15], data_map[55][55][2]; //0 正 1 倒 int col_num[55][2]; bool isOK, num_map[26]; bool cmp(const int &a, const int &b) { return a<b; } int DFS_ROW(int row, int col, int choice) { int i, j, lenth, k, s, last_lenth; bool ok ; switch (choice) { case CHOICE_R: for (; col <= col_num[row][1]; col++) { if (data_map[row][col][0]) { break; } } if (col > col_num[row][1]) { return DFS_ROW(row, col_num[row][0], CHOICE_C); } last_lenth = col; for (i = 0; i< triangle_num; i++) { lenth = triangle[i]; if (row+lenth > 2*side_len || col+lenth-1 > col_num[row][1]) { return 0; } for (k = last_lenth; k < col+lenth; k++) { if (!data_map[row][k][0]) //已被填充 { return 0; //失败 } } last_lenth = k; for (j = row; j< row+lenth; j++) { for (k = col; k < col+lenth-j+row; k++) { data_map[j][k][0] = 0; if (k != col) { data_map[j][k][1] = 0; } } }//寻找下个点 ok = 1; for (j = col+lenth; j<= col_num[row][1]; j++) { if (data_map[row][j][0]) { if (DFS_ROW(row, j, CHOICE_R)) { return 1; } else { ok = 0; } break; } } if (j > col_num[row][1]) { if (!DFS_ROW(row, col_num[row][0], CHOICE_C)) ok = 0; else return 1; } //恢复点 if (!ok) { for (s = row; s< row+lenth; s++) { for (k = col; k < col+lenth-s+row; k++) { data_map[s][k][0] = 1; if (k != col) { data_map[s][k][1] = 1; } } } } } break; case CHOICE_C: for (; col <= col_num[row][1]; col++) { if (data_map[row][col][1]) { break; } } if (col > col_num[row][1]) { if (row == 2*side_len-1) //搜索完毕 return 1; else return DFS_ROW(row+1, col_num[row][0], CHOICE_R); } for (i = 0; i< triangle_num; i++) { lenth = triangle[i]; if (row+lenth > 2*side_len || col > col_num[row+lenth-1][1] || col-lenth+1 < col_num[row+lenth-1][0]) { return 0; } for (j = row, k = col; j< row+lenth && k > col-lenth; j++, k--) { if (!data_map[j][col][1] || !data_map[j][k][1]) { return 0; } } for (j = row; j< row+lenth; j++) { for (k = col-j+row; k <= col ; k++) { data_map[j][k][1] = 0; if (k != col) { data_map[j][k][0] = 0; } } }//寻找下个点 ok = 1; for (j = col+1; j<= col_num[row][1]; j++) { if (data_map[row][j][1]) { if (DFS_ROW(row, j, CHOICE_C)) { return 1; } else { ok = 0; } break; } } if (j > col_num[row][1]) { if (row == 2*side_len-1) return 1; if (!DFS_ROW(row+1, col_num[row+1][0], CHOICE_R)) ok = 0; else return 1; } //恢复点 if (!ok) { for (j = row; j< row+lenth; j++) { for (k = col-j+row; k <= col ; k++) { data_map[j][k][1] = 1; if (k != col) { data_map[j][k][0] = 1; } } } } } break; } return 0; } inline void solve() { memset(data_map, 0, sizeof(data_map)); int i, j; for (i = 0; i<= side_len; i++) { for (j = side_len - i; j <= side_len*2; j++) { data_map[i][j][0] = data_map[i][j][1] = 1; if (j == side_len*2) { data_map[i][j][0] = 0; } } col_num[i][0] = side_len - i; col_num[i][1] = side_len*2; } for (i = side_len; i< 2*side_len; i++) { for (j = 0; j < 3*side_len-i; j++) { data_map[i][j][0] = data_map[i][j][1] = 1; if ( j == 0 ) { data_map[i][j][1] = 0; } } col_num[i][0] = 0; col_num[i][1] = 3*side_len-i-1; } data_map[side_len][2*side_len][1] = 0; if (DFS_ROW(0, side_len, CHOICE_R)) { isOK = 1; } } int main() { int sum, i, j, k, tmp_triangle[15]; cin>>sum; while (sum--) { cin>>side_len>>triangle_num; isOK = 0; k = 0; memset(num_map, 0, sizeof(num_map)); for (i = 0; i< triangle_num; i++) { cin>>tmp_triangle[i]; if (side_len % tmp_triangle[i] == 0) { isOK = 1; goto my_stop; } if (tmp_triangle[i] > side_len) { isOK = 0; goto my_stop; } if (!num_map[tmp_triangle[i]]) { triangle[k++] = tmp_triangle[i]; for (j = tmp_triangle[i]; j < 26; j += tmp_triangle[i]) { num_map[j] = 1; } } } triangle_num = k; sort(triangle, triangle+triangle_num, cmp); solve(); my_stop: if (isOK) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }