第13次CCF计算机软件能力认证

A

跳一跳

//比赛中可以直接用万能头文件
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
//开longlong防止爆掉int,int范围2e9,longlong范围9e18
#define int long long //(有超时风险)
//简写,如果要改动PII,直接该这个就行了,vector常用
#define PII pair<int,int>
//#define x first
//#define y second

using namespace std;

//需要改动数组直接改动N,M即可
const int N=2e5+10,M=1e3+10;
int sum=0;
int w[N],q[N],t[M];
int a,b,c;

signed main()
{
    //关掉流同步,cin变快,但是不能用scanf,可以用printf;
    std::ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    for(int i=1;i<=30;i++)cin>>w[i];
    for(int i=1;i<=30;i++)
    {
        if(w[i]==0)break;
        else if(w[i]==1&&w[i+1]==2)w[i+1]=2;
        else if(w[i]>=2&&w[i+1]==2)w[i+1]=w[i]+2;
        else if(w[i-1]>=2&&w[i]==2&&w[i+1]==1)w[i]=w[i-1]+2;
    }
    for(int i=1;i<=30;i++)
    {
        if(w[i]==0)break;
        else sum+=w[i];
        //else cout<<w[i]<<" ";
    }
    cout<<sum;

    return 0;
}

B

碰撞的小球

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n,L,T;
struct Ball
{
    int p,v;//位置,速度
}b[N];

int main()
{
    cin>>n>>L>>T;
    for(int i=0;i<n;i++)
    {
        cin>>b[i].p;
        b[i].v=1;
    }
    
    while(T--)
    {
        for(int i=0;i<n;i++)
        {
            b[i].p+=b[i].v;
            if(b[i].p==L||!b[i].p)
               b[i].v*=-1;
        }
        
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(b[i].p==b[j].p)
                {
                    b[i].v*=-1;
                    b[j].v*=-1;
                }
            }
        }
    }
    
    for(int i=0;i<n;i++)
       cout<<b[i].p<<" ";
       
    return 0;
}
//向右的速度是1,那么向左的速度就是-1,每次位置的变化等于位置加速度
//写两个循环,暴力枚举

C

#include<iostream>
#include<cstring>
#include<vector>

using namespace std;

const int N = 110;

struct Url
{
    string path;
    string name;
}url[N];//使用结构体进行存储规则中的路径与名称

int n, m;

string check_num(string &str)//检查测试用例中的参数中是否为数字类型
{
    string res;//若参数为数字类型,则返回数字字符串;否则返回长度为0的字符串

    for(int i = 0; i < str.size(); i ++)
    {
        if(str[i] >= '0' && str[i] <= '9')//如果是数字,则将数字加入到res中
        {
            res += str[i];
        }
        else//否则,清空res(返回空字符串)
        {
            res.clear();
            return res;
        }
    }

    int k = 0;//去掉前导0
    while(k + 1 < res.size() && res[k] == '0') k ++;//从k + 1开始枚举,避免只有一位0但是被删除的特例
    return res.substr(k);//从第k个字符开始取字符串
}

vector<string> get(string &path, string &str)//测试用例str与规则path进行匹配
{
    vector<string> res(1);//初始化匹配结果(默认长度为1)如果长度为0,则说明匹配失败;否则返回测试用例的参数
    int i, j;

    for(i = 1, j = 1; i < path.size() && j < str.size();)//使用双指针算法,分别寻找测试用例str与规则path中,被/分割的字符串
    {
        int u = i + 1, v = j + 1;//从输入第二个字符开始寻找(输入的第一个字符全部为/,没有意义)

        while(u < path.size() && path[u] != '/') u ++;//寻找下一个/的下标,用来寻找测试用例以及规则中的参数
        while(v < str.size() && str[v] != '/') v ++;

        //substr(int start, int length) 返回从第start个字符开始,长度为length的子字符串
        //在本题中,起始时i为参数的第一个下标,从小到大开始寻找从i最近的/的前一个下标u. 下标[i, u]就表示当前参数的标识
        string a = path.substr(i, u - i), b = str.substr(j, v - j);//使用substr函数取出/string/

        if(a == "<str>")//如果规则中当前的参数为<str>
        {
            res.push_back(b);//则直接将测试用例的参数加入到res中
            i = u + 1, j = v + 1;//开始定位下一个参数的开头(u为/的下标,所以要从 u + 1开始进行下一次匹配)以下同理
        }
        else if(a == "<int>")//如果规则中当前的参数为<int>
        {
            auto t = check_num(b);//将测试用例的参数b判断是否为数字
            if(!t.empty())//如果是数字(返回字符串不为空)
            {
                res.push_back(t);//将去掉前导0的字符加入匹配结果中
                i = u + 1, j = v + 1;
            }
            else
            {
                res.clear();//否则匹配失败,清空字符串
                return res;
            }
        }
        else if(a == "<path>")//如果规则中当前的参数为<path>
        {
            res.push_back(str.substr(j));//则将剩余的字符串全部加入到参数序列中
            return res;//path后直接结束
        }
        else if(a != b)//规则匹配完毕,开始数据进行匹配;如果不等,则匹配失败
        {
            res.clear();//返回空字符串
            return res;
        }
        else i = u + 1, j = v + 1;//普通字符串不是参数,不用存,比如说articles就不用存
    }
    //对于最后一位有没有/的特殊条件也要作为一个特殊判断
    //如果测试用例和规则的结尾都没有/时,那么i能取到path.size() + 1
    //(因为在之前的匹配中,我们总能寻找到最后一个/的下标u,如果最后没有/,则说明u能取到path.size(),这样i在加上1就等于path.size() + 1
    //如果测试用例和规则的结尾都有/时,那么i能取到path.size()
    //(因为u只能返回/的前一个字符下标,i = u + 1时 i正好表示规则字符的长度)
    if(i - path.size() != j - str.size()) res.clear();//所以只需要判断i - path.size() 与 j - str.size()是否相等,就能判断在结尾是否都有或都没有/

    return res;
}

void work(string &str)//返回匹配测试用例与所有规则进行匹配的结果
{
    for(int i = 0; i < n; i ++)
    {
        auto res = get(url[i].path, str);//将规则与测试用例进行匹配,返回测试用例中传入的参数
        //get函数()返回匹配后参数的个数.如果匹配不成功,返回0个数据();如果匹配成功,但测试用例中的参数为0,则返回一个长度为1的默认参数
        //如果匹配成功并且传入的参数不为空,则返回传入的参数(第一个返回值为默认值,后面的值才是实际传入的参数)

        if(res.size())//如果匹配成功
        {
            cout << url[i].name;//首先输出规则的名称
            for(int j = 1; j < res.size(); j ++)
            {
                cout << ' ' << res[j];//之后遍历所有测试用例的参数
            }
            cout << endl;
            return ;
        }
    }
    puts("404");//如果不匹配,则返回404
}

int main()
{
    cin >> n >> m;

    for(int i = 0; i < n; i ++)//读入所有规则
    {
        cin >> url[i].path >> url[i].name;
    }

    for(int i = 0; i < m; i ++)//将测试用例读入
    {
        string test;
        cin >> test;

        work(test);//处理询问
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值