Time Limit: 2000MS | Memory Limit: 32768K | |
Total Submissions: 1098 | Accepted: 510 |
Description
Input
Output
Sample Input
3 5 2 2 3 7 2 3 2 13 2 2 3
Sample Output
NO NO YES
Source
#include <iostream> #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; const int N = 101; int lcm[30]; bool map[N][N]; int border[4][30][2]; int border4[55][2]; int n,s; bool flag; void getborder() { memset(border,0,sizeof(border)); memset(border4,0,sizeof(border4)); int i,j; int ss = s * 2; border[1][1][1] = ss - 1; border[1][1][0] = 1; for(i = 2;i <= s;i ++) { border[1][i][0] = 1;//类型1的第i行左边界为1 border[1][i][1] = border[1][i - 1][1] - 2; } for(i = 1;i <= s;i ++) { border[2][i][0] = 1; border[2][i][1] = ss; } border[3][1][0] = 1; border[3][1][1] = ss * 2 - 1; for(i = 2;i <= s;i ++) { border[3][i][0] = 1; border[3][i][1] = border[3][i - 1][1] - 2; } border4[1][0] = ss; border4[1][1] = ss * 2; for(i = 2;i <= s;i ++) { border4[i][0] = border4[i - 1][0] - 2; border4[i][1] = border4[i - 1][1]; } border4[s + 1][0] = 1; border4[s + 1][1] = ss * 2 - 1; for(i = s + 2;i <= ss;i ++) { border4[i][0] = 1; border4[i][1] = border4[i - 1][1] - 2; } //for(i = 1;i <= ss;i ++) // printf("row:%d left:%d right:%d\n",i,border4[i][0],border4[i][1]); } void predeal() { int i,j,k; for(i = 1;i < n;i ++) { k = 0; for(j = i + 1;j <= n;j ++) if(lcm[j] % lcm[i] == 0) { lcm[j] = 73; k ++; } if(k) sort(lcm + 1,lcm + 1 + n); n -= k; } } void dfs(int cur,int len) { if(flag) return ; if(len > s) return ; if(len == s) { flag = true; return; } for(int i = 1;i <= n;i ++) dfs(i,len + lcm[i]); } int nextint() { char c; int ret = 0; while(isspace(c = getchar())) ; ret = c - '0'; while((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + c - '0'; return ret; } bool canput1(int row,int col,int len) { if(row + len - 1 > s + s) return false; int i,j; if(col & 1) { int dp = 0; for(i = row + len - 1;i >= row;i --) { for(j = col;j <= col + dp;j ++) if(map[i][j] || j > border4[i][1] || j < border4[i][0]) return false; dp += 2; } } else { int dp = 0; for(i = row;i <= row + len - 1;i ++) { for(j = col;j >= col - dp;j --) if(map[i][j] || j > border4[i][1] || j < border4[i][0]) return false; dp += 2; } } return true; } bool canput2(int row,int col,int len,int type) { if(row + len - 1 > s) return false; int i,j; if(col & 1) { int dp = 0; for(i = row + len - 1;i >= row;i --) { for(j = col;j <= col + dp;j ++) if(map[i][j] || j > border[type][i][1] || j < border[type][i][0]) return false; dp += 2; } } else { int dp = 0; for(i = row;i <= row + len - 1;i ++) { for(j = col;j >= col - dp;j --) if(map[i][j] || j > border[type][i][1] || j < border[type][i][0]) return false; dp += 2; } } //printf("canput %d %d %d\n",row,col,len); return true; } void put(int row,int col,int len,int add) { int i,j,dp; if(col & 1) { dp = 0; for(i = row + len - 1;i >= row;i --) { for(j = col;j <= col + dp;j ++) map[i][j] = add; dp += 2; } } else { dp = 0; for(i = row;i <= row + len - 1;i ++) { for(j = col - dp;j <= col;j ++) map[i][j] = add; dp += 2; } } //printf("put in %d %d len %d %d\n",row,col,len,add); //system("pause"); } void Dfs(int x,int y,int type,int num) { //printf("%d %d\n",x,num); if(flag) return; int j,k; bool f = false; if(type < 4) { if(x >= s) return; for(j = y;j <= border[type][x][1];j ++) { if(!map[x][j]) { f = true; for(k = 1;k <= n;k ++) { if(canput2(x,j,lcm[k],type)) { if(num == lcm[k] * lcm[k]) { flag = 1; return; } put(x,j,lcm[k],1); int tmp = j; if(j & 1) tmp += (lcm[k] * 2 - 1); else tmp ++; if(tmp > border[type][x][1]) Dfs(x + 1,1,type,num - lcm[k]*lcm[k]); else Dfs(x,tmp,type,num - lcm[k] * lcm[k]); put(x,j,lcm[k],0); } else return; } } } if(f == false)//如果第x行都被放了,去x+1行找 Dfs(x + 1,1,type,num); } else { if(x >= s + s)//取等号是因为一定没有边长为1的三角形(已处理),上同 return; for(j = y;j <= border4[x][1];j ++) { if(!map[x][j]) { f = true; for(k = 1;k <= n;k ++) { if(canput1(x,j,lcm[k])) { if(num == lcm[k] * lcm[k]) { flag = 1; return; } put(x,j,lcm[k],1); int tmp = j; if(j & 1) tmp += (lcm[k] * 2 - 1); else tmp ++; if(tmp > border4[x][1]) Dfs(x + 1,1,type,num - lcm[k] * lcm[k]); else Dfs(x,tmp,type,num - lcm[k] * lcm[k]); put(x,j,lcm[k],0); } else return; } } } if(f == false) Dfs(x + 1,1,type,num); } } int main() { int i,j,k; int t; t = nextint(); while(t --) { s = nextint(); n = nextint(); flag = false; for(i = 1;i <= n;i ++) { lcm[i] = nextint(); if(lcm[i] > s) { i --; n --; continue; } if(s % lcm[i] == 0) flag = true; } if(flag)//剪枝1 { printf("YES\n"); continue; } sort(lcm + 1,lcm + 1 + n);//剪枝5 predeal();//剪枝2 flag = false; for(i = 1;i <= n;i ++) dfs(i,lcm[i]);//剪枝3 if(flag == false) { printf("NO\n"); continue; } flag = false; int num; getborder(); for(i = 1;i <= 4 && flag == false;i ++)//剪枝4 i从1-4分别表示六边形的1/6,1/3,1/2,1/1 { //printf("%d\n",i); memset(map,0,sizeof(map)); if(i < 4) num = s * s * i; else num = s * s * 6; Dfs(1,1,i,num);//row,col,type } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }