题目
题目链接:http://poj.org/problem?id=1017
题目来源:《挑战》练习题
简要题意:给定 1×1⋯6×6 物品的个数,求最少需要多少个 6×6 的箱子可以放入这些物品。
数据范围:未知
题解
一道题意简单,但是需要仔细讨论的好题。
6×6 直接放入就行了。
5×5 每个都必须占一个箱子,最好的情况就是填上 11 个 1×1 。
4×4 每个必须占一个箱子,最好的情况是塞上 2×2 物品, 2×2 可以折换成 1×1 ,因此忽略。
3×3 最好的情况就是 4 个凑出一个,如果有多出来需要分情况讨论,比较复杂。
2×2 最好是 9 个凑出一个,空余的可以折合成4 个 1×1 的。1×1 的话只能 36 个凑一个。
实现
仔细分情况就行了,比较难分析的是 3×3 的时候的情况。
给的样例非常好,可以察觉到其中的玄机。
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
int a[15];
void cal5(int &ans) {
ans += a[5];
a[1] = max(a[1]-a[5]*11, 0);
}
void cal4(int &ans) {
ans += a[4];
a[2] -= a[4]*5;
}
void cal3(int &ans) {
ans += (a[3]+3)/4;
int rest = a[3]%4;
if (rest == 1) {
a[2] -= 5;
a[1] -= 7;
} else if (rest == 2) {
a[2] -= 3;
a[1] -= 6;
} else if (rest == 3) {
a[2] -= 1;
a[1] -= 5;
}
}
void cal2(int &ans) {
if (a[2] > 0) {
ans += (a[2]+8)/9;
int rest = (9-a[2]%9)%9;
a[1] -= rest*4;
} else {
a[1] += a[2]*4;
}
}
void cal1(int &ans) {
if (a[1] > 0) {
ans += (a[1]+35)/36;
}
}
int main()
{
while (1) {
int sum = 0;
for (int i = 1; i <= 6; i++) {
scanf("%d", a+i);
sum += a[i];
}
if (!sum) break;
int ans = a[6];
cal5(ans);
cal4(ans);
cal3(ans);
cal2(ans);
cal1(ans);
printf("%d\n", ans);
}
return 0;
}