CCF 历届真题--持续更新ing

1 跳一跳

描述

近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱。
  简化后的跳一跳规则如下:玩家每次从当前方块跳到下一个方块,如果没有跳到下一个方块上则游戏结束。
  如果跳到了方块上,但没有跳到方块的中心则获得1分;跳到方块中心时,若上一次的得分为1分或这是本局游戏的第一次跳跃则此次得分为2分,否则此次得分比上一次得分多两分(即连续跳到方块中心时,总得分将+2,+4,+6,+8…)。
  现在给出一个人跳一跳的全过程,请你求出他本局游戏的得分(按照题目描述的规则)。

分析

模拟场景,还是很简单那种。一个sum记录总分,一个last记录上一层得分,1的时候直接sum++;2的时候根据last来加分并修改last的值,0的时候输出并return

参考代码

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int n,sum=0,last=1;
    while (cin>>n)
    {
        if (n == 1){sum++;last =1;}
        else if(n==2)
        {
            if (last == 1){sum += 2;last = 2;}
            else {
                sum += (last + 2);
                last += 2;
            }

        }
        else{
            cout<<sum<<"\n";
            return 0;
        }
    }


}

2 碰撞的小球

描述

数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。
  当小球到达线段的端点(左端点或右端点)的时候,会立即向相反的方向移动,速度大小仍然为原来大小。
  当两个小球撞到一起的时候,两个小球会分别向与自己原来移动的方向相反的方向,以原来的速度大小继续移动。
  现在,告诉你线段的长度L,小球数量n,以及n个小球的初始位置,请你计算t秒之后,各个小球的位置。
  因为所有小球的初始位置都为偶数,而且线段的长度为偶数,可以证明,不会有三个小球同时相撞,小球到达线段端点以及小球之间的碰撞时刻均为整数。
  同时也可以证明两个小球发生碰撞的位置一定是整数(但不一定是偶数)。

分析

也是模拟题,用了location数组记录每个小球的位置;v数组记录每个小球的速度;LL二维数组(vector)记录每个整数位置的小球的编号。在时间t下循环,每次遍历一遍所有小球,根据v[i]修改其位置;遍历完后遍历位置,所有一个位置处小球数大于1的(只会有两个),将这两个编号小球的速度去相反数。看起来有点啰嗦

代码

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
const int maxx = 200;
const int Lmax = 1005;
int locations[maxx];
vector<vector<int> >LL;
int v[maxx];
int main()
{
    int n, L, t;
    while (cin >> n >> L >> t)
    {
        LL.clear();
        LL.resize(L + 1);
        for (int i = 0; i < n; i++)
        {
            cin >> locations[i];
            v[i] = 1;
        }

        while (t>0)
        {
            LL.clear();
            LL.resize(L + 1);
            for (int i = 0; i < n; i++)
            {
            if (locations[i] == L) {
            v[i] = -v[i];
            }

            locations[i] += v[i];
            LL[locations[i]].push_back(i);
            }
            for(int i =0;i<LL.size();i++)
                if (LL[i].size() > 1)
                {
                    v[LL[i][0]] = -v[LL[i][0]];
                    v[LL[i][1]] = -v[LL[i][1]];
                }
        t--;
        }
        for (int i = 0; i < n; i++)
            printf("%d ", locations[i]);
    }
    return 0;
}

不知道为什么,在vs2017上这个报vector下标越界,但是我提交之后就过了。。过了

上面那个方法有点啰嗦,习惯了直接无视O(n^2)级别的算法,没想到也能过。就是遍历查找此刻有没有位置相同的,然后修改两者的方向就好了!O(n^2)!过了!

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxx = 200;
const int Lmax = 1005;
int locations[maxx];
int v[maxx];
int main()
{
    int n, L, t;
    while (cin >> n >> L >> t)
    {

        for (int i = 0; i < n; i++)
        {
            cin >> locations[i];
            v[i] = 1;
        }

        while (t>0)
        {
            //if (locations[0] == 0 && v[0] < 0)v[0] = -v[0];
            //if (locations[0] == L)v[0] = -v[0];
            //locations[0] = locations[0] + v[0];
            for (int i = 0; i < n; i++)
            {
                if (locations[i] == L || (locations[i] == 0&&v[i]<0))v[i] = -v[i];
                locations[i] = locations[i] + v[i];
                for(int j =0;j<n;j++)
                if (locations[i] == locations[j])
                {
                    v[i] = -v[i];
                    v[j] = -v[j];
                }
            }
        t--;
        }
        for (int i = 0; i < n; i++)
            printf("%d ", locations[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/beforeeasy/article/details/80081890
今日推荐