题意:
View Code
给你最多10种边长范围在1~25的正三角形,问能不能用它们拼成一个指定边长(指定的范围也是1~25)的正六边形(每种三角形使用的个数没有限制)。图1是一个用边长为2和3的三角形拼成边长为9的正六边形的例子。
具体代码:
//此题难再见坐标,其他OK。。 //dfs用小正三角覆盖大正三角,问能否完全覆盖 //120坐标系建立 //画图自己研究。。。。。。、 //逐行DFS,填完一行在下一行。从下往上 从左往右 //一个三角一个三角覆盖 //判断能够覆盖的时候,小三角不行大三角一定不行 //背包优化。。这里没用 , 还有一种剪枝也没用 就是先判断1/2 1/3 1/6的覆盖。。。 //a[i]%a[j]==0就不要a[i]了; //注意如果sz%a[i]==0 那么直接可以了。。。。 #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cstdio> using namespace std; #define MAXN 110 int sz,a[15],n,tp; int g[MAXN][MAXN]; bool jud1() { for(int i=0;i<tp;i++) if(sz%a[i]==0) return true; return false; } //120度建立坐标 //横向扩大2 纵向不便,具体理解自己画图 void init() { memset(g,0,sizeof(g)); for(int i=1;i<=sz;i++) for(int j=1;j<=sz*2+2*i-1;j++) g[i][j]=1; for(int i=sz+1;i<=sz*2;i++) for(int j=(i-sz)*2;j<=sz*4;j++) g[i][j]=1; } bool judSZ(int x,int y,int size) { if(y+2*size-2>sz*4 || x+size-1>sz*2) return false; if(y%2==1) //倒三角 规律自己画图看注意列坐标 { for(int i=0;i<size;i++) for(int j=0;j<2*i+1;j++) if(!g[x+i][y+j]) return false; } else //正三角 { for(int i=0;i<size;i++) for(int j=2*i;j<2*size-1;j++) if(!g[x+i][y+j]) return false; } return true; } //覆盖回复和上面检查能否覆盖一样 void cover(int x,int y,int size) { if(y%2==1) { for(int i=0;i<size;i++) for(int j=0;j<2*i+1;j++) g[x+i][y+j]=0; } else { for(int i=0;i<size;i++) for(int j=2*i;j<2*size-1;j++) g[x+i][y+j]=0; } } void remove(int x,int y,int size) { if (y%2==1) { for(int i=0;i<size;i++) for(int j=0;j<2*i+1;j++) g[x+i][y+j]=1; } else { for(int i=0;i<size;i++) for(int j=2*i;j<2*size-1;j++) g[x+i][y+j]=1; } } bool dfs(int x,int y) { if(x>sz*2) return true; if(y>sz*4) return dfs(x+1,1); if(!g[x][y]) { int j; for(j=y+1;y<=4*sz;y++) if(g[x][j]) break; return dfs(x,j); } for(int i=0;i<tp;i++) { if(judSZ(x,y,a[i])) { cover(x,y,a[i]); if(dfs(x,y+1)) return true; remove(x,y,a[i]); } else break; } return false; } int main() { int cs; cin>>cs; while(cs--) { cin>>sz; cin>>n; tp=0; for(int i=0;i<n;i++) { scanf("%d",&a[tp++]); // if(a[tp]<=sz) tp++; } for(int i=0;i<tp;i++) for(int j=0;j<tp;j++) { if(i==j) continue; if(a[i]%a[j]==0) { swap(a[i],a[tp-1]); i--,tp--; break; } } sort(a,a+tp); if(jud1()) { printf("YES\n"); continue; } init(); if(dfs(1,1)) printf("YES\n"); else printf("NO\n"); } return 0; }