CCF-CSP 201803 赛题训练
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF-CSP 201803 赛题训练相关的知识,希望对你有一定的参考价值。
CCF-CSP 201803 赛题训练
跳一跳
题目
近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱。
简化后的跳一跳规则如下:玩家每次从当前方块跳到下一个方块,如果没有跳到下一个方块上则游戏结束。
如果跳到了方块上,但没有跳到方块的中心则获得1分;跳到方块中心时,若上一次的得分为1分或这是本局游戏的第一次跳跃则此次得分为2分,否则此次得分比上一次得分多两分(即连续跳到方块中心时,总得分将+2,+4,+6,+8…)。
现在给出一个人跳一跳的全过程,请你求出他本局游戏的得分(按照题目描述的规则)。
输入
输入包含多个数字,用空格分隔,每个数字都是1,2,0
之一,1表示此次跳跃跳到了方块上但是没有跳到中心,2表示此次跳跃跳到了方块上并且跳到了方块中心,0表示此次跳跃没有跳到方块上(此时游戏结束)。
输出
输出一个整数,为本局游戏的得分(在本题的规则下)。
输入样例
1 1 2 2 2 1 1 2 2 0
输出样例
22
直接模拟存储加分:
#include<bits/stdc++.h>
using namespace std;
int main()
int a, ans = 0, pre = 0;
while (cin >> a)
if (a == 0)
break;
if (a == 1) // 非中心+1分
ans++;
pre = 1;
else if (pre == 1 || pre == 0) // 若是首次调中心+2
ans += 2;
pre = 2;
else // 连续2,则需要比前一次多+2
ans += pre+2;
pre += 2;
cout << ans;
解法二:存储步数 Link
变量step用于存储当前连续得2分的步数。step初值为0,连续得2分则每次增加1步并且得分为setp*2,如果得1分(没有跳到中心)则连续得2分的步数变为0。
变量score用于存储当前的得分。
#include<stdio.h>
int main()
int a, score = 0, step = 0;
while (scanf("%d", &a) != EOF && a)
if (a == 1) score++, step = 0;
else if (a == 2) score += ++step * 2;
printf("%d\\n", score);
return 0;
碰撞的小球
题目
数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。
当小球到达线段的端点(左端点或右端点)的时候,会立即向相反的方向移动,速度大小仍然为原来大小。
当两个小球撞到一起的时候,两个小球会分别向与自己原来移动的方向相反的方向,以原来的速度大小继续移动。
现在,告诉你线段的长度L,小球数量n,以及n个小球的初始位置,请你计算t秒之后,各个小球的位置。
输入
输入的第一行包含三个整数n, L, t,用空格分隔,分别表示小球的个数、线段长度和你需要计算t秒之后小球的位置。 第二行包含n个整数a1,
a2, …, an,用空格分隔,表示初始时刻n个小球的位置。
输出
输出一行包含n个整数,用空格分隔,第i个整数代表初始时刻位于ai的小球,在t秒之后的位置。
输入样例1
3 10 5
4 6 8
输出样例1
7 9 9
输入样例2
10 22 30
14 12 16 6 10 2 8 20 18 4
输出样例2
6 6 8 2 4 0 4 12 10 2
样例说明
问题分析
这是一个模拟题,按照时间序列进行模拟,模拟小球的运动过程。好在每个时间单位小球只移动一个位置,处理起来就要简单一些。模拟题关键在于采用什么样的数据表示,这里给出2种解法。
方法一(不排序,暴力):
使用数组pos[i]存储第i个球的初始位置;使用数组step[i]存储第i个球现在的运动方向,step[i]=1表示向右走,step[i]=-1表示往左走,用加法运算就可以实现小球的移动。
太巧了,直接解决了左右方向问题
模拟过程是按照时间序列,先计算小球的下一个位置,如果该位置为两端则改变运动方向。再根据小球的新位置看看有没有2个小球碰头,有的话分别改变运动方向。只是简单地判断2个小球是否碰头需要用暴力法算一下。
- 大佬代码:Link
#include<bits/stdc++.h>
using namespace std;
const int L = 1000;
int pos[L + 1], step[L + 1];
int main()
int n, l, t;
cin >> n >> l >> t; // 输入时间,小球数量,长度
for(int i = 0; i < n; i++)
cin >> pos[i];
// 开始往右走,到达两端则回头
step[i] = 1;
if(pos[i] == l || pos[i] == 0)
step[i] = -step[i];
for(int i = 0; i < t; i++)
// 走一步
for(int j = 0; j < n; j++)
pos[j] += step[j];
// 到达两端则回头
if(pos[j] == l || pos[j] == 0)
step[j] = -step[j];
// 判断是否碰头,碰头则掉头(要避免重复比较)
for(int j = 0; j < n; j++)
for(int k = j + 1; k < n; k++)
if(pos[k] == pos[j])
step[k] = -step[k], step[j] = -step[j];
for(int i = 0; i < n; i++)
cout << pos[i] << " ";
cout << endl;
return 0;
- 排序代码:Link
加油!
感谢!
努力!
以上是关于CCF-CSP 201803 赛题训练的主要内容,如果未能解决你的问题,请参考以下文章