Big Chocolate
Mohammad has recently visited Switzerland. As he loves his friends very much, he decided to buy some chocolate for them, but as this fine chocolate is very expensive(You know Mohammad is a little BIT stingy!), he could only afford buying one chocolate, albeit a very big one (part of it can be seen in figure 1) for all of them as a souvenir. Now, he wants to give each of his friends exactly one part of this chocolate and as he believes all human beings are equal (!), he wants to split it into equal parts.
The chocolate is an
rectangle constructed from
unit-sized
squares. You can assume that Mohammad has also
friends waiting to receive their piece of chocolate.
To split the chocolate, Mohammad can cut it in vertical or horizontal direction (through the lines that separate the squares). Then, he should do the same with each part separately until he reaches
unit
size pieces of chocolate. Unfortunately, because he is a little lazy, he wants to use the minimum number of cuts required to accomplish this task.
Your goal is to tell him the minimum number of cuts needed to split all of the chocolate squares apart.

Figure 1. Mohammad’s chocolate
The Input
The input consists of several test cases. In each line of input, there are two integers
, the number of rows in the chocolate and
,
the number of columns in the chocolate. The input should be processed until end of file is encountered.
The Output
For each line of input, your program should produce one line of output containing an integer indicating the minimum number of cuts needed to split the entire chocolate into unit size pieces.
Sample Input
2 2
1 1
1 5
Sample Output
3
0
4
——————————————————————
解题思路:
本题是非常简单的一题,但要注意不能用递归法,否则会超时。
正确的方法其实就是

假设上面就是我们要切的巧克力,橙色的边表示切痕,而且是只有橙色边的位置才会有切痕,如果每条短边都视作一刀的话,那么上面那个巧克力显然要切17刀,这也是最坏的情况了,那么刀数为什么可以比17刀少呢?我们不妨观察红点的位置,如果左右刀痕连在了一起那么可以少一刀,同理如果上下刀痕连一起,也可以少一刀,但是上下和左右的刀痕不能同时连一起。那么也就是说如果有一个红色的这样的点,那么就可以使上下刀痕连一起,或者左右刀痕连一起,从而减少一刀,那么一共有6个这样的点,就可以减少6刀,所以最优就是11刀。
————————————————————————————-
代码:
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
int split(int M, int N)
{
if (M == 1 && N == 1)
return 0;
else if (M >= N)
return 1 + split(M / 2, N) + split(M - M / 2, N);
else
return 1 + split(M, N / 2) + split(M, N - N / 2);
}
int main()
{
int M, N;
while (cin >> M >> N)
{
//cout<<split(M, N)<<endl;
<span style="white-space:pre"> </span>cout << M*N - 1<<endl;
}
}
巧分巧克力

本文介绍了一个有趣的问题:如何将一块矩形巧克力分成等份送给朋友,同时尽量减少切割次数。通过分析,给出了一个高效的计算方法来确定最少切割次数。

被折叠的 条评论
为什么被折叠?



