链接:https://vjudge.net/problem/POJ-1020
题意:
给一个宽为s的正方形,再给n个变长为an的小正方形,
判断是否能将这n个小正方形完全填充到这个大正方形里面。
思路:
首先判断总面积是否相等。
用一维数组记录每一列用了多少的高度。
每次选择剩余高度最长的 ,再找出对应的长度。
从大往小的选择正方形往里填充。
如果刚好填充完,则满足。
代码:
#include <iostream> #include <memory.h> #include <vector> #include <map> #include <algorithm> #include <cstdio> #include <math.h> #include <queue> #include <string> using namespace std; typedef long long LL; const int MAXN = 60; int square[MAXN]; int col[MAXN]; int n, m; bool DFS(int num) { if (num == n) return true; int minVal = m; int minOrd = 0; for (int i = 1;i <= m;i++) { //填充最小的列 if (col[i] < minVal) { minVal = col[i]; minOrd = i; } } int minNum = 0; for (int i = minOrd;i <= m;i++) { //得到填充最小的列的行数 if (col[i] == minVal) minNum++; else break; } //从10往1填 for (int i = 10;i >= 1;i--) { if (square[i] <= 0) continue; if (i <= m - col[minOrd] && i <= minNum) { square[i]--; for (int j = minOrd;j < minOrd + i;j++) col[j] += i; if (DFS(num + 1)) return true; for (int j = minOrd;j < minOrd + i;j++) col[j] -= i; square[i]++; } } return false; } int main() { int t; int wid; scanf("%d", &t); while (t--) { int sum = 0; memset(square, 0, sizeof(square)); memset(col, 0, sizeof(col)); scanf("%d%d", &m, &n); for (int i = 1;i <= n;i++) { cin >> wid; square[wid]++; sum += wid * wid; } if (sum != m * m) { cout << "HUTUTU!" << endl; continue; } if (DFS(0)) cout << "KHOOOOB!" << endl; else cout << "HUTUTU!" << endl; } return 0; }