CCF 2018真题--持续更新ing

8 篇文章 0 订阅

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;
}

3 URL映射

描述

问题描述
  URL 映射是诸如 Django、Ruby on Rails 等网页框架 (web frameworks) 的一个重要组件。对于从浏览器发来的 HTTP 请求,URL 映射模块会解析请求中的 URL 地址,并将其分派给相应的处理代码。现在,请你来实现一个简单的 URL 映射功能。
  本题中 URL 映射功能的配置由若干条 URL 映射规则组成。当一个请求到达时,URL 映射功能会将请求中的 URL 地址按照配置的先后顺序逐一与这些规则进行匹配。当遇到第一条完全匹配的规则时,匹配成功,得到匹配的规则以及匹配的参数。若不能匹配任何一条规则,则匹配失败。
  本题输入的 URL 地址是以斜杠 / 作为分隔符的路径,保证以斜杠开头。其他合法字符还包括大小写英文字母、阿拉伯数字、减号 -、下划线 _ 和小数点 .。例如,/person/123/ 是一个合法的 URL 地址,而 /person/123? 则不合法(存在不合法的字符问号 ?)。另外,英文字母区分大小写,因此 /case/ 和 /CAse/ 是不同的 URL 地址。
  对于 URL 映射规则,同样是以斜杠开始。除了可以是正常的 URL 地址外,还可以包含参数,有以下 3 种:
  字符串 :用于匹配一段字符串,注意字符串里不能包含斜杠。例如,abcde0123。
  整数 :用于匹配一个不带符号的整数,全部由阿拉伯数字组成。例如,01234。
  路径 :用于匹配一段字符串,字符串可以包含斜杠。例如,abcd/0123/。
  以上 3 种参数都必须匹配非空的字符串。简便起见,题目规定规则中 和 前面一定是斜杠,后面要么是斜杠,要么是规则的结束(也就是该参数是规则的最后一部分)。而 的前面一定是斜杠,后面一定是规则的结束。无论是 URL 地址还是规则,都不会出现连续的斜杠。
输入格式
  输入第一行是两个正整数 n 和 m,分别表示 URL 映射的规则条数和待处理的 URL 地址个数,中间用一个空格字符分隔。
  第 2 行至第 n+1 行按匹配的先后顺序描述 URL 映射规则的配置信息。第 i+1 行包含两个字符串 pi 和 ri,其中 pi 表示 URL 匹配的规则,ri 表示这条 URL 匹配的名字。两个字符串都非空,且不包含空格字符,两者中间用一个空格字符分隔。
  第 n+2 行至第 n+m+1 行描述待处理的 URL 地址。第 n+1+i 行包含一个字符串 qi,表示待处理的 URL 地址,字符串中不包含空格字符。
输出格式
  输入共 m 行,第 i 行表示 qi 的匹配结果。如果匹配成功,设匹配了规则 pj ,则输出对应的 rj。同时,如果规则中有参数,则在同一行内依次输出匹配后的参数。注意整数参数输出时要把前导零去掉。相邻两项之间用一个空格字符分隔。如果匹配失败,则输出 404。
样例输入
5 4
/articles/2003/ special_case_2003
/articles// year_archive
/articles/// month_archive
/articles article_detail
/static/ static_serve
/articles/2004/
/articles/1985/09/aloha/
/articles/hello/
/static/js/jquery.js
样例输出
year_archive 2004
article_detail 1985 9 aloha
404
static_serve js/jquery.js
样例说明
  对于第 1 个地址 /articles/2004/,无法匹配第 1 条规则,可以匹配第 2 条规则,参数为 2004。
  对于第 2 个地址 /articles/1985/09/aloha/,只能匹配第 4 条规则,参数依次为 1985、9(已经去掉前导零)和 aloha。
  对于第 3 个地址 /articles/hello/,无法匹配任何一条规则。
  对于第 4 个地址 /static/js/jquery.js,可以匹配最后一条规则,参数为 js/jquery.js。
数据规模和约定
  1 ≤ n ≤ 100,1 ≤ m ≤ 100。
  所有输入行的长度不超过 100 个字符(不包含换行符)。
  保证输入的规则都是合法的。

分析

这道题卡了很久..
算是一道大模拟的题,看上去不是很难,但是没那么容易过,最后的AC代码参考了 https://blog.csdn.net/nameofcsdn/article/details/79945925
m条URL每一个都要在n条规则中寻找一遍有没有匹配的,还是把一条url与一条规则是否匹配单拿出来做函数的好
这位博主的代码用一个bool参数来确定这次是单纯判断是否符合还是输出匹配的参数,反正我没想到
判断的时候用while循环比用for循环灵活许多,相等就continue;出现不等的情况,如果规则处不是’<’那肯定是不匹配了,return FALSE;
如果是’<’的话,就分三种情况:‘i’判断数字,如果一直是数字就可以一直输出,开始时判断是否为0即可,如果不满足这条规则就return false了,如果这个int匹配上了,就可以continue进行下一步了;
‘s’判断str,输出直到出现’/’为止;’p’判断path,输出直到最后。
最后如果没有出现这些个参数的话,如果两个一直匹配,那最后各自到达自己的长度时,就是完全匹配了

灵活使用continue return,让代码变得很简洁

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cctype>
using namespace std;
string rules[101],names[101], qs[101];
bool ismatch(string q, string rule,   bool flag)
{
    int qlen = q.length(), rlen = rule.length();
    int qi = 0, ri = 0;
    while (qi<qlen && ri<rlen)
    {
        if (q[qi] == rule[ri])
        {
            qi++; ri++; continue;
        }
        if (rule[ri++] != '<')return false;
        if (flag)cout << " ";
        if (rule[ri] == 'i') {
            bool flag2 = false;
            while (qi < qlen && q[qi] >= '0' && q[qi] <= '9')
            {
                if (q[qi] > '0')flag2 = true;
                if (flag && flag2)cout << q[qi];
                qi++;
            }
            if (flag2 == false)return false;
            ri += 4;
            continue;
        }
        else if (rule[ri] == 's')
        {
            bool flag2 = false;
            while (qi<qlen && q[qi]!='/' )
            {
                flag2 = true;
                if (flag2 && flag)cout << q[qi];
                qi++;
            }
            if (flag2 == false)return false;
            ri += 4;
            continue;
        }
        else if (rule[ri] == 'p')
        {
            while (qi<qlen)
            {
                if (flag)cout << q[qi];
                qi++;
            }
            return true;
        }
    }
    return (qi == qlen && ri == rlen);
}
int main()
{
    int n, m;
    while (cin>>n>>m)
    {
        for (int i = 0; i < n; i++)
        {
            cin >> rules[i]>>names[i];
        }
        string q;
        for (int i = 0; i < m; i++) {
            cin >> q;
            bool fl = false;
            for(int j=0;j<n;j++)
                if (ismatch(q, rules[j], false))
                {
                    fl = true;
                    cout << names[j] ;
                    ismatch(q, rules[j], true);
                    cout << "\n";
                    break;
                }
            if (fl == false)cout << "404\n";
        }



    }
}
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值