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
#include
#include
#include
#include
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;
}