ZOJ 3407 Doraemon's Cake Machine [数学]

题意:

最多有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
");
            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
",ans);
    }
}
原文地址:https://www.cnblogs.com/tun117/p/5412065.html