POJ 2590 Steps

来源:互联网 发布:aspose.cells java 编辑:程序博客网 时间:2024/06/04 19:57

这道题证明我真的是一个大脑简单的人物,看到这句“The length of a step must be nonnegative and can be by one bigger than, equal to, or by one smaller than the length of the previous step”我一直认为是从x 到y 第一步为1 最后一步为1 中间每个step可以比上一个长,短或者一般长,当时我的第一反应是,这道题的答案永远小于等于3 ,第一步是1 最后一步是1 中间一步是(y-x)-2;我还奇怪为什么poj上会出这么那啥啥的题,再看下面的数据为什么会有4,搞不明白啦,why ,看别人的程序还是不明白为甚?再次读题,忽然发现“”can be by one bigger than, equal to, or by one smaller than the length of the previous step“ 我把那个one自动消除了,哎,这道题的意思是,某一步的长度可以比上一步的长度长一,短一,或者等于上一步的长度,求最少的步数

既然可以长短,等,又让求最少的步数,那就先递增,在递减,中间某些数字重复

例如:

x=0 y=49

1 2 3 4 5 6 7  6 5 4 3 2 1


x=0 y=50

1 2 3 4 5 6 7 6 5 4 3 2 1 1


x=0 y=51

1 2 3 4 5 6 7 6 5 4 3 2 2 1


x=0 y=56

1 2 3 4 5 6 7 7 6 5 4 3 2 1


但是数据量可是很大的,我们如何能够缩短时间哩

假如 两个递增数列的最大值分别为 a b 且a>b t为剩余

m=a*(a+1)/2+b*(b+1)/2+t>b*(b+1)>b*b;

则n=sqrt(m) >sqrt(b*(b+1))>b

为了保险起见我们令n=sqrt(m)+1;

从n开始

令s=i*(i+1)/2+(i-1)*i/2;

找到使s<=(y-x)的i 求出steps 与上一次的比较,找出最小的,如果比上一次的大那么直接跳出程序,因为越往后越大

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int x,y;
int fun(int m,int left)
{
int s;
s=0;
if(left==0)
return 0;
if(left<=m)
return 1;
while(left-m>0)
{
left-=m;
s++;
}
if(left>0)
s++;
return s;
}
int main()
{
int k,i;
int n,m;
int si;
int s;
int steps;
scanf("%d\n",&k);
while(k--)
{
scanf("%d%d",&x,&y);
if(x==y)
{
printf("0\n");
continue;
}
steps=0xfffffff;
m=abs(x-y);
n=(int)sqrt((double)m)+1;
int flag=0;
for(i=n;i>=1;i--)
{
s=(i*(i-1))/2+((i+1)*i)/2;
if(m<s)
continue;
si=2*i-1+fun(i,m-s);
if(steps>si)
{
steps=si;
flag=1;
}else if(flag==1)
break;
}
printf("%d\n",steps);
}
return 0;
}

据听说这道题是有一个跟好的算法的,可惜我现在心情很high,看不下去,等我平静了再说吧

原创粉丝点击