题意:给你一块蛋糕,要用m步,将他分为n份相等的,问你最少用的copy操作数,你可以用1个机器对蛋糕进行横切和竖切,还可以copy但是只能copy一块蛋糕,而且copy后只能进行copy的操作,不能过再切了,比赛的时候把题目读成了copy之后就停了,切的时候要保证是对所有的蛋糕的操作。 当时也没看到,结果觉得很难,因为封榜没人过,没想到是水题,做过的人也不厚道,竟然打好代码等封榜后交,这招太贱了,搞得当时就没怎么认真看。师兄他们也是这样吧。。。都跟着做其他难的。
首先分析假设横切了y刀,竖切了x刀,copy了z次,那么就可以列出式子:2*x*(y+1)+z=n;x+y+z=m;由这两个式子求解需要注意x为0,显然枚举求解,两个式子联立2*x*y+x+-y+m=n;显然x*y-x-y<=n显然由对称性只要枚举x和y到根号n即可,太亏了。。。
Run ID | Submit Time | Judge Status | Problem ID | Language | Run Time(ms) | Run Memory(KB) | User Name |
2643895 | 2011-08-29 23:33:44 | Accepted | 3407 | C++ | 150 | 188 | xym |
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
int c,n,m;
scanf("%d",&c);
while(c--)
{
scanf("%d%d",&n,&m);
if(n<=m)
{
printf("-1\n");
continue;
}
if(n-m==1)
{
printf("0\n");
continue;
}
double tem=sqrt(n*1.0);
int ans=0x7fffffff;
for(int x=1;x<=tem;x++)
{
int y=(n-m-x)/(2*x-1);
int z=m-x-y;
if(y<0||z<0||2*x*(y+1)+z!=n||ans<z) continue;
ans=z;
}
for(int y=1;y<=tem;y++)
{
int x=(n-m+y)/(2*y+1);
int z=m-x-y;
if(x<0||z<0||2*x*(y+1)+z!=n||ans<z) continue;
ans=z;
}
if(ans!=0x7fffffff)
printf("%d\n",ans);
else
printf("-1\n");
}
return 0;
}