标签:
题意:
最多有2000组测试样例,每组样例代表n,m;
n代表要把蛋糕平分的份数,m代表必须进行多少次操作。
一共有三种操作
1.竖切 经过蛋糕圆心,将蛋糕整个向下切。
2.横切 平行于蛋糕平面进行平切。
3.复制某块小蛋糕 这种操作只能在1和2所有操作都进行完才能进行。
求:
最少进行多少次复制操作可以将蛋糕分为一样的恰好n种。注意需要用恰好m次操作。
如果没有可行解输出-1。
思路:
假设进行三种操作的数目分别是xyz。然后连立两个式子把z消掉,get
2x(y+1)-(x+y)=n-m;
因为x+y+z=m且z>=0所以有x+y<=m;
所以有2x(y+1)<=n;
进而xy<n;(x和y都是非负整数)
所以得到结论在符合要求的等式中必定有x<=sqrt(n)||y<=sqrt(n);
所以对两者枚举到sqrt(n)即可。
坑:
我们应该明白,每次进行操作至少会使得蛋糕的数量增加1.所以当m>=n的时候直接输出-1.
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; const int inf=0x3f3f3f3f; int main() { int t; scanf("%d",&t); while(t--){ long long ans=inf,n,m; scanf("%lld%lld",&n,&m); if(n<=m){ printf("-1\n"); continue; } for(int i=1;i<=sqrt(n)+1;i++){ if((n-m-i)%(2*i-1)==0&&n-m-i>=0){ long long y=(n-m-i)/(2*i-1); if(i+y<=m){ ans=min(ans,m-i-y); } } } for(int i=0;i<=sqrt(n)+1;i++){ if((n-m+i)%(2*i+1)==0&&n-m+i>=0){ long long x=(n-m+i)/(2*i+1); if(i+x<=m){ ans=min(ans,m-i-x); } } } if(m+1==n)ans=0; if(ans==inf)ans=-1; printf("%lld\n",ans); } }
ZOJ 3407 Doraemon's Cake Machine [数学]
标签:
原文地址:http://www.cnblogs.com/tun117/p/5412065.html