非常经典的模拟题,首先需要建立120°坐标系,然后dfs
以下是AC的代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 bool map[52][52]; 5 int num, n, list[11], test; 6 void printmap(){ 7 int i, j; 8 for (i = 1; i <= 2 * n; ++i){ 9 for (j = 1; j<4 * n; ++j) printf("%d ", map[i][j]); 10 printf("\n"); 11 } 12 printf("\n\n"); 13 } 14 bool canput(int r, int c, int len){ 15 int i, j; 16 if (r + len - 1 > 2 * n || c + len - 1 > 4 * n) return 0; 17 if (c % 2 == 0){ 18 for (i = r; i < r + len; ++i) 19 for (j = c + 2 * (i - r); j < c + 2 * (i - r) + 2 * len - 1 - 2 * (i - r); ++j) 20 if (map[i][j]) return 0; 21 } 22 else{ 23 for (i = r; i < r + len; ++i) 24 for (j = c; j < c + 2 * (i - r + 1) - 1; ++j) 25 if (map[i][j]) return 0; 26 } 27 return 1; 28 } 29 void put(int r, int c, int len){ 30 int i, j; 31 if (c % 2 == 0){ 32 for (i = r; i < r + len; i++) 33 for (j = c + 2 * (i - r); j < c + 2 * (i - r) + 2 * len - 1 - 2 * (i - r); j++) 34 map[i][j] = 1; 35 } 36 else{ 37 for (i = r; i < r + len; i++) 38 for (j = c; j < c + 2 * (i - r + 1) - 1; j++) 39 map[i][j] = 1; 40 } 41 //printmap(); 42 } 43 void deput(int r, int c, int len){ 44 int i, j; 45 if (c % 2 == 0){ 46 for (i = r; i < r + len; i++) 47 for (j = c + 2 * (i - r); j < c + 2 * (i - r) + 2 * len - 1 - 2 * (i - r); j++) 48 map[i][j] = 0; 49 } 50 else{ 51 for (i = r; i<r + len; i++) 52 for (j = c; j<c + 2 * (i - r + 1) - 1; j++) 53 map[i][j] = 0; 54 } 55 } 56 bool detect(int r, int c){ 57 if (r>2 * n) return 1; 58 else if (c>4 * n) return detect(r + 1, 1); 59 else if (map[r][c]){//找到第一个0的位置 60 int i; 61 for (i = c; i <= 4 * n; ++i) 62 if (!map[r][i]) break; 63 return detect(r, i); 64 } 65 else{ 66 for (int i = 1; i <= num; ++i){ 67 if (canput(r, c, list[i])){ 68 put(r, c, list[i]); 69 if (detect(r, c + 1)) return 1; 70 deput(r, c, list[i]); 71 } 72 else break; 73 } 74 return 0; 75 } 76 } 77 int cmp(const void *a, const void *b){ 78 return *(int *)a - *(int *)b; 79 } 80 int main(){ 81 #ifndef ONLINE_JUDGE 82 freopen("sample_input.txt", "r", stdin); 83 #endif 84 scanf("%d", &test); 85 for (int i = 1; i <= test; ++i){ 86 bool flag = 0; 87 scanf("%d%d", &n, &num); 88 for (int j = 1; j <= num; ++j) scanf("%d", &list[j]); 89 qsort(list + 1, num, sizeof(int), cmp); 90 for (int j = 1; j <= num; ++j){/*优化*/ 91 if (n%list[j] == 0){ 92 printf("YES\n"); 93 flag = 1; 94 break; 95 } 96 if (list[j] > n){ 97 num = j - 1; 98 break; 99 } 100 } 101 if (flag) continue; 102 for (int j = 1; j <= num; j++) 103 for (int k = 1; k < j; k++){ 104 if (list[j] % list[k] == 0){ 105 for (int l = j; l < num; ++l) list[l] = list[l + 1]; 106 j--; 107 num--; 108 break; 109 } 110 } 111 /*---------------------------------------------*/ 112 memset(map, 1, sizeof(map)); 113 for (int j = 1; j <= n; j++) 114 for (int k = 1; k <= 2 * n + 1 + (j - 1) * 2; k++) 115 map[j][k] = 0; 116 for (int j = n + 1; j <= 2 * n; j++) 117 for (int k = (j - n) * 2; k <= 4 * n; k++) 118 map[j][k] = 0; 119 printmap(); 120 if (detect(1, 1)) printf("YES\n"); 121 else printf("NO\n"); 122 } 123 return 0; 124 }