题意:
最多有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=;i<=sqrt(n)+;i++){
if((n-m-i)%(*i-)==&&n-m-i>=){
long long y=(n-m-i)/(*i-);
if(i+y<=m){
ans=min(ans,m-i-y);
}
}
}
for(int i=;i<=sqrt(n)+;i++){
if((n-m+i)%(*i+)==&&n-m+i>=){
long long x=(n-m+i)/(*i+);
if(i+x<=m){
ans=min(ans,m-i-x);
}
}
}
if(m+==n)ans=;
if(ans==inf)ans=-;
printf("%lld\n",ans);
}
}