题目描述:
Alice、Bob 和 Cindy 三个好朋友得到了一个圆形蛋糕,他们打算分享这个蛋糕。
三个人的需求量分别为 a,b,c现在请你帮他们切蛋糕,规则如下:
-
每次切蛋糕可以选择蛋糕的任意一条直径,并沿这条直径切一刀(注意切完后不会立刻将蛋糕分成两部分)。
-
设你一共切了 n 刀,那么你将得到 2n 个扇形的蛋糕(特别地,切了 0 刀被认为是有一个扇形,即整个圆形蛋糕),将这些蛋糕分配给 Alice,Bob 和 Cindy,要求每个扇形蛋糕只能完整地分给一个人。
-
三人分到的蛋糕面积比需要为 a:b:c(不保证是最简比例,且如果 a:b:c 中某个数为 0,表示那个人不吃蛋糕)。
为了完成这个任务,你至少需要切几刀?
输入格式:
本题单个测试点包含多组数据。
第一行包含一个整数 T,表示数据组数。
接下来 T 行,每行包含三个整数 a,b,c,表示三人的需求量。
输出格式:
输出 T 行,第 i 行的输出表示第 i组数据中你至少需要切蛋糕的次数。
输入输出样例:
输入 #1:
6 0 0 8 0 5 3 9 9 0 6 2 4 1 7 4 5 8 5
输出 #1:
0 2 1 2 3 2
说明/提示
样例 1 解释:
数据范围与提示
30% 的数据满足:a=b=0。
60% 的数据满足:a=0。
100% 的数据满足:1≤T≤10^4,0≤a,b,c≤10^8,保证 a+b+c>0。
思路:
这一道题做法是分类讨论。
假设 a≤b≤c,那么就有以下结论:
● a,b 等于 0
很明显,一刀都不用切,全部给 c就可以了,切零刀。
● 有且仅有 a 等于 0
● b=c
在这种情况下,分出两半分别给 b,c 即可,切一刀。
● b≠c
在这种情况下,切一刀肯定是不行的。但是,容易证明,切两刀可以将蛋糕分成任意比例的两份。因此切两刀。
● a,b,c≠0且 a=b(b=c 同理)
可以切两刀,分成的四份中,取任意相同的两份给 a,b,剩下相同的两份给 c 即可(按照a=0&b!=c 的结论推出)
● a,b,c≠0且 a+b=c
可以切两刀,分成的四份中,取两份不同的给 a,b,剩下不同的两份给 c 便可以满足 a+b=c;依然按照 a=0&b!=c 的结论得到,上述情况可以成立。
● 否则
切三刀。根据 a=0&b!=c 的结论容易扩展得,切三刀可以分成任意三份的比例。
容易证明,切两刀可以将蛋糕分成任意比例的两份。
对于这一段的证明如下:
设圆的面积为 S,切两刀得到如下:
由于这两道是随意切的,所以 k 可以取到 0<k<1 的所有值。因此,同样颜色的扇形面积之和也可以取到 0<S'<S 的所有值。
代码:
#include<bits/stdc++.h> //万能头文件
using namespace std; //批准使用std类
int main(){ ///main主函数
int t; //样例数
cin>>t; //输入
while(t--){ //输入t个样例
int a[3]; //定义a,b,c
cin>>a[0]>>a[1]>>a[2]; //输入
sort(a,a+3); //排序,要满足a<=b<=c
if(a[0]==0&&a[1]==0) //第一种情况
cout<<"0"<<endl; //输出0
else if(a[0]==0){ //如果一个为0
if(a[1]==a[2]) //看看另外两人是否相等
cout<<"1"<<endl; //相等就切一刀
else //不相等
cout<<"2"<<endl; //切两刀(以证明切两刀能分出所有比例)
}
else{ //如果三个都没有为0的
if(a[0]==a[1]||a[1]==a[2]||(a[0]+a[1]==a[2])) //如果有任意两个相等或者第一个加第二个等于第三个
cout<<"2"<<endl; //就只用切2刀
else //否则
cout<<"3"<<endl; //切三刀
}
}
return 0; //结束
}
总结;
这道题作为NOI Online 2021的第一题,还是比较简单的,只需要手推一下,就可以进行分支判断了!
题目链接:
[NOI Online 2021 入门组] 切蛋糕 - 洛谷https://www.luogu.com.cn/problem/P7471