手工(handicraft)
【题目描述】
小 D 对于手工有一种独特的热情。这一天他得到了一个凸 n 边
形, 每次他可以沿着 任意一条 直线, 将 一块多边形用鱼片劈成两部分。
为了装饰鱼片,他需要得到至少 p 个 m 边形。但是小 D 又很吝惜自
己的鱼片的耐久度,所以他希望用最少的 次数来完成这项工作。
【输入数据】
输入第一行一个正整数 T,表示数据组数。
接下来 T 行,每行三个正整数 n,m,p,意义如题干中所述相同。
【输出数据】
输出 T 行,每行一个整数,表示最少需要劈几次才能完成工作。
【样例输入】
1
8 4 3
【样例输出】
2
【数据范围】
对于 10%的数据,p=1;
对于 40%的数据,p<=10;
另外 20%的数据,m=3;
对于 100%的数据,1<=T<=5,3<=n,m<=10^9,1<=p<=10^9。
思路:
易得,切一个n边形有三种情况。
1:n-m+2,m
2:n-m+3,m
3:n-m+4,m
所以,切p个m要一个pm-4p+4变形切p-1次;
我们可以分类讨论
当n<pm-4p+4 可以切三角形,把n加到pm-4p+4.
当pm-4p+4<=n<=pm-2p+2 可以发现,无论多少,都可以切除p个m边形。
当n>pm-2p+2 最后一刀切出的多边形的边数一定大于m,所以一定要再切一刀。
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 int t,n,m,p; 7 long long h,hh,daan; 8 int main() 9 { 10 //freopen("handicraft.in","r",stdin); 11 //freopen("handicraft.out","w",stdout); 12 cin>>t; 13 while(t--) 14 { 15 daan=0; 16 cin>>n>>m>>p; 17 h=1LL*(p-1)*(m-4)+m; 18 hh=1LL*(p-1)*(m-2)+m; 19 if(n<h) 20 { 21 daan=h-n+p-1; 22 } 23 else if(n<=hh) 24 { 25 daan=p-1; 26 } 27 else 28 { 29 daan=p; 30 } 31 cout<<daan<<endl; 32 } 33 return 0; 34 }