目录
Day 1
上午 9:00 - 11:00,摸底测试
T1:弹跳蚱蜢
时间限制:1000ms 空间限制:256MB
输入文件:jump.in 输出文件:jump.out
题目描述
现在,有一只蚱蜢位于一个数轴上x0 处。
因为它无事可做,便灵机一动,开始在数轴上进行弹跳训练。因为蚱蜢非常喜欢正整数,因此,在最开 始的第一分钟,它会向前跳1个单位的长度,在第二分钟,它会向前跳2个单位的长度,以此类推。而蚱 蜢觉得一直的往前跳跃也没啥意思,因此,它规定,如果在这一次跳跃前,它处于的点坐标为偶数,那 么,它就会向左跳,否则,它才会向右跳。
例如:如果在连续的18次跳跃之后,蚱蜢到达了坐标点7,在它进行第19次跳跃时,因为它当前所处的 位置是奇数,所以,它会往右跳跃19个单位长度到达坐标点19+7=26。在它进行第20次跳跃时,因为当 前所处的坐标点26是偶数,所以,它会向左跳跃20个单位长度到达坐标点26-20=6.
现在,已知蚱蜢最初始的坐标点 的大小,请你求出当蚱蜢跳跃 次以后到达的位置。
输入格式
第一行输入一个数字t(1 ≤ t ≤ 1e4) ,表示样例的测试数量。
接下来 行,每行两个数字,第一个数字x0(-1e14 ≤ x0 ≤ 1e14) ,表示蚱蜢的初始位置,第二个数字 n(1 ≤ t ≤ 1e14),表示跳跃的次数。
输出格式
对于每一个问题,输出跳跃n次后到达的坐标点位置。
输入样例
9
0 1
0 2
10 10
10 99
177 13
10000000000 987654321
-433494437 87178291199
1 0
-1 1
输出样例
-1
1
11
110
190
90
12345679
-87611785637
1
0
样例解释
解析
对于第一个问题。蚱蜢的初始位置在坐标0处,因为0是一个偶数,因此,蚱蜢首先会向左跳1个单位长度,因此第一个问题的答案为-1.
对于第二个问题,蚱蜢的初始位置在坐标0初,因为0是一个偶数,因此,第一次向左跳一个单位长度到 达-1,因为-1是一个奇数,因此,第二次向右跳2到达坐标点1,得到答案。
很容易,我们根据题意模拟,即可得到以下代码:
#include <bits/stdc++.h>
using namespace std;
int T;
long long x, n;
int main() {
scanf("%d", &T);
while(T--) {
scanf("%lld%lld", &x, &n);
for (int i = 1;i <= n;i++) {
if (x & 1) {
x += i;
} else {
x -= i;
}
}
printf("%lld\n", x);
}
return 0;
}
注意:
(1)x 一定要定义成长整型(long long int)。
(2)“x & 1”中‘&’是位运算,这里是用于判断x是否能被2整除。
那么,恭喜你,TLE,0分。
那么,如何优化呢?
找规律!
顺便说说,如何更快更准更高级的找规律。
首先,你需要一个暴力程序,和一个数据生成程序。
如下:
暴力程序:
#include <bits/stdc++.h>
using namespace std;
int T;
long long x, n;
int main() {
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
scanf("%d", &T);
while(T--) {
scanf("%lld%lld", &x, &n);
for (int i = 1;i <= n;i++) {
if (x & 1) {
x += i;
} else {
x -= i;
}
}
printf("%lld\n", x);
}
return 0;
}
很显然,我们应该从起点为奇数和起点为偶数开始分别找规律。
数据生成程序:
1.偶数:
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("1.in", "w", stdout);
int T = 20;
cout << 20 << endl;
while(T--) {
cout << 0 << " " << 20 - T << endl;
}
return 0;
}
所以,输入数据:
20
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
0 10
0 11
0 12
0 13
0 14
0 15
0 16
0 17
0 18
0 19
0 20
输出数据:
-1
1
4
0
-5
1
8
0
-9
1
12
0
-13
1
16
0
-17
1
20
0
2.奇数:
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("1.in", "w", stdout);
int T = 20;
cout << 20 << endl;
while(T--) {
cout << 1 << " " << 20 - T << endl;
}
return 0;
}
所以,输入数据:
20
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20
输出数据:
2
0
-3
1
6
0
-7
1
10
0
-11
1
14
0
-15
1
18
0
-19
1
这不,规律出来了。
#include <bits/stdc++.h>
using namespace std;
long long T, x, n, xx;
int main() {
//freopen("jump.in", "r", stdin);
//freopen("jump.out", "w", stdout);
scanf("%lld", &T);
while(T--) {
scanf("%lld%lld", &x, &n);
long long xxx = abs(x);
if (xxx % 2 == 1) {
//cout << "B";
if (n % 4 == 1) {
xx = n;
} else if (n % 4 == 2) {
xx = -1;
} else if (n % 4 == 3) {
xx = -1 * n - 1;
} else {
xx = 0;
}
} else {
if (n % 4 == 1) {
xx = -1 * n;
} else if (n % 4 == 2) {
xx = 1;
} else if (n % 4 == 3) {
xx = n + 1;
} else {
xx = 0;
}
}
//cout << x << " " << xx << endl;
printf("%lld\n", x + xx);
}
return 0;
}
AC!47ms