问题 C: 小兔蹦蹦跳Ⅰ
时间限制: 1 Sec 内存限制: 128 MB
提交: 465 解决: 138
[提交][状态][讨论版]
题目描述
小兔位于X轴的x点,欲跳至X轴的y点。x,y均为整数。小兔每次沿x轴直线跳跃,每跳的长度均为正整数,假设
小兔一共跳了n次才到目的地,每次跳的长度为F1,F2,..., Fn. 有规则如下:
F1=Fn=1
|Fi-Fi-1|<=1 , 2<=i<=n (注:| |是绝对值符号)
我们的问题是给定x,y, 如何使得n最小。
输入
包含多组数据,但不超过1000组。每组数据一行,每行包括两个整数x和y。0 <= x < y <= 1000000000 。
输出
对于每一组数据,输出一行,即从x到y的最小跳跃次数n。
样例输入
45 48
45 49
45 50
样例输出
3
3
4
题解:测试一些数据,找规律
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define loop(i,L,R) for(int i=(L);i<=(R);i++)
const int maxn=1e5+5;
int main()
{
int n,x,y;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&x,&y);
int d=y-x;
if(d<=3)
{
printf("%d\n",d);
continue;
}
int mid=sqrt(d);
int s=mid*(mid+1);
if(mid*mid==d)
printf("%d\n",2*mid-1);
else if(mid*(mid+1)>=d) printf("%d\n",2*mid);
else printf("%d\n",mid*2+1);
}
}
/**
131 321
27
31 231
28
32 123
19
45 421
38
76 567
44
23 234
29
13 343
36
*/
问题 D: 小兔蹦蹦跳Ⅱ
时间限制: 3 Sec 内存限制: 128 MB Special Judge
提交: 212 解决: 28
[提交][状态][讨论版]
题目描述
小兔位于X轴的x点,欲跳至X轴的y点。x,y均为整数。小兔每次沿x轴直线跳跃,每跳的长度均为正整数,假设
小兔一共跳了n次才到目的地,每次跳的长度为F1,F2,..., Fn. 有规则如下:
F1=Fn=1
|Fi-Fi-1|<=1 , 2<=i<=n (注:| |是绝对值符号)
我们的问题是给定x,y, 求出使得n最小的具体跳跃方案,最佳方案数不一定唯一,输出一种即可。
跳跃方案的输出规则解释如下:
本题有输出大小限制,指导性原则是为了减少输出数据,建议尽可能把形成等差数列的Fi合并在一起。一个最佳方案可能有多条记录组成,每条记录包含一个Fi或者多个Fi的数据,记录的次序必须符合Fi的先后顺序。
每条记录可能是下面两种格式之一:
(1)A start end
类型A表示从start 到end是等差数列,start不等于end。start小于end表示Fi中的等差数列为start, start+1,..,end. start大于end表示Fi中的等差数列为start, start-1,..,end.
例如 A 3 7 表明 3 4 5 6 7 是Fi系列的一部分
而A 7 3表明 7 6 5 4 3 是Fi系列的一部分
(2)B v
类型B表示v是Fi系列中的某一次跳跃长度。
下面给出一个具体的例子:
假定x=0, y=9,
那么最小的n应该是5, F1=1, F2=2, F3=3, F4=2, F5=1.
可以有如下输出方案:
2
A 1 3
A 2 1
也可以有如下输出方案:
2
A 1 2
A 3 1
也可以有如下输出方案:
3
B 1
A 2 3
A 2 1
也可以有如下输出方案:
4
B 1
B 2
B 3
A 2 1
输出方案的第一行表示跳跃方案有多少条记录。
输入
包含多组数据,不超过400000组。每组数据一行,每行包括两个整数x和y。0 <= x < y <= 1000000000 。
输出
对于每一组数据,输出多行。具体信息如下:
(1)第一行表示该组数据的最佳跳跃方案有m行记录。
(2)随后有m行,要求按跳跃的先后次序记录。详细说明见上。
样例输入
45 48
45 49
45 50
样例输出
3
B 1
B 1
B 1
2
A 1 2
B 1
3
B 1
A 1 2
B 1
题解:当mid*mid=d时,按照上一题的方法,此时应该只有2行记录,但由于未特别处理,导致WA了几次.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define loop(i,L,R) for(int i=(L);i<=(R);i++)
const int maxn=1e5+5;
int main()
{
int x,y;
while(scanf("%d%d",&x,&y)==2)
{
int d=y-x;
if(d<=3)
{
printf("%d\n",d);
for(int i=0;i<d;i++) printf("B 1\n");
continue;
}
else if(d==4)
{
printf("2\n");
printf("A 1 2\n");
printf("B 1\n");
continue;
}
int mid=sqrt(d);
if(mid*mid==d)
{
printf("2\n");
printf("A 1 %d\n",mid);
printf("A %d 1\n",mid-1);
continue;
}
if(mid*(mid+1)==d)
{
printf("2\n");
printf("A 1 %d\n",mid);
printf("A %d 1\n",mid);
continue;
}
else if(mid*(mid+1)>d)
{
int k=mid*(mid+1)-d;
if(k&1)
{
if(k==1)
{
printf("3\n");
printf("A 1 %d\n",mid);
printf("B %d\n",mid-1);
if(mid==2) printf("B %d\n",mid-1);
else printf("A %d 1\n",mid-1);
continue;
}
printf("4\n");
int kk=(k+1)/2;
if((mid-kk)!=1) printf("A 1 %d\n",mid-kk);
else printf("B 1\n");
if(kk!=1) printf("A %d %d\n",mid-kk,mid-1);
else printf("B %d\n",mid-1);
if(kk==2)
{
printf("B %d\n",mid-1);
if(mid==kk) printf("B %d\n",mid-kk+1);
else printf("A %d 1\n",mid-kk+1);
}
else
{
printf("A %d %d\n",mid-1,mid-kk+1);
if(mid!=kk) printf("A %d 1\n",mid-kk+1);
else printf("B 1\n");
}
}
else
{
printf("4\n");
int kk=k/2;
if((mid-kk)!=1) printf("A 1 %d\n",mid-kk);
else printf("B 1\n");
if(kk!=1) printf("A %d %d\n",mid-kk,mid-1);
else printf("B %d\n",mid-1);
if(kk!=1) printf("A %d %d\n",mid-1,mid-kk);
else printf("B %d\n",mid-1);
if(kk==2)
{
if((mid-kk)==1) printf("B %d\n",mid-kk);
else printf("A %d 1\n",mid-kk);
}
else
{
if((mid-kk)!=1) printf("A %d 1\n",mid-kk);
else printf("B 1\n");
}
}
}
else
{
int k=d-mid*(mid+1);
printf("3\n");
printf("A 1 %d\n",mid);
if(mid!=k) printf("A %d %d\n",mid,k);
else printf("B %d\n",k);
if(k==1) printf("B 1\n");
else printf("A %d 1\n",k);
}
}
}