【poj1020】 Anniversary Cake
http://poj.org/problem?id=1020 (题目链接)
题意
有一个S*S的大蛋糕,还有许多正方形的小蛋糕,问能否将大蛋糕完整的分成所有的小蛋糕,不能有剩余。
Solution
像这种看起来很麻烦的基本上都是水题,然而poj上的所谓水题,我也是呵呵了。
在根据题意做完若干判断剪枝后,我们开始搜索。因为蛋糕不能有剩余,所以搜索就很好搜了,刚开始没注意不知道,直接参考了别人的程序→_→。详情请见:题解
代码
// poj1020 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define MOD 100000000 #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=100; int a[maxn],c[maxn],n,S;; bool dfs(int x) { if (x==n) return 1; int tmp=50,p; for (int i=1;i<=S;i++) if (tmp>c[i]) tmp=c[i],p=i; for (int i=10;i;i--) //枚举 if (a[i] && S-c[p]>=i && S-p+1>=i) { int w=0; for (int j=p;j<=p+i-1;j++) { if (c[j]==c[p]) w++; //因为必须放满,所以不能留空 else break; } if (w==i) { a[i]--; for (int j=p;j<=p+i-1;j++) c[j]+=i; if (dfs(x+1)) return 1; a[i]++; for (int j=p;j<=p+i-1;j++) c[j]-=i; } } return 0; } int main() { int T;scanf("%d",&T); while (T--) { memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); scanf("%d%d",&S,&n); int cnt=0,area=0; for (int x,i=1;i<=n;i++) { scanf("%d",&x); area+=x*x; a[x]++; if (x>S/2) cnt++; } if (cnt>1 || area!=S*S) {printf("HUTUTU!\n");continue;} if (dfs(0)) printf("KHOOOOB!\n"); else printf("HUTUTU!\n"); } return 0; }
This passage is made by MashiroSky.