201803 CSP认证 | 跳一跳 碰撞的小球 URL映射

1. 跳一跳
15 ms | 100分

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int res = 0, begin = 1, x, pre = 0;
    while(cin >> x) {
        if(!x) break; //游戏结束
        if(x == 1){
            res ++;
            pre = 1;
        }
        
        else {
            if(begin || pre == 1){   //如果是刚开局就跳了中心或者之前的得分为1
                res += 2;
                pre = 2;
            }
            else {
                pre += 2;
                res += pre;
            }
        }
        begin = 0;
    }
    cout << res;
    return 0;
}

2. 碰撞的小球
15ms | 100分

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N], dir[N];
map<int, int> pos;  //记录某个位置上存在的小球标号
//感觉n和t都较小可以直接暴力做
int main()
{
    int n, L, t;
    cin >> n >> L >> t;

    int MAX = 0, index;
    for(int i = 1;i <= n;i ++){
        scanf("%d", &a[i]);
        dir[i] = 1;
        if(a[i] > MAX){
            MAX = a[i]; 
            index = i;   //找到位置最右的小球
        }
    }

    //第一个转向的小球之前必然无碰撞,整体向右平移
    int delta = L - MAX;
    for(int i = 1;i <= n;i ++) a[i] += delta;
    dir[index] = -1 * dir[index];  //最右小球转向

    for(int i = delta + 1;i <= t;i ++){  //暴力计算,每一个时刻
        pos.clear();
        for(int i = 1;i <= n;i ++){
            a[i] += dir[i];
            
            //判断是否到达边界
            if(a[i] == L || a[i] == 0)  dir[i] = -1 *dir[i];
            
            //判断是否发送碰撞
            if(pos.count(a[i])){  //如果当前新位置已经存在有小球,做反向处理(同一时刻只有可能两球相撞)
                index = pos[a[i]];
                //两个小球都进行反向
                dir[i] = -1 *dir[i];
                dir[index] = -1 *dir[index];
            }
            else {
                pos[a[i]] = i;  //记录下:当前位置有小球i
            }
        }
    }

    for(int i = 1;i <= n;i ++)  printf("%d ", a[i]);
    return 0;
}

3. URL映射
15ms | 100分
耗时我两三个小时我终于写出了一个跟字符串有关的模拟大题了呜呜
在99行代码改错改了特别热别久,也就是对于下面这个测试用例

本来没有if判断的,会导致最后是否由 / 来结尾判断不清(一个本来已经超过,一个刚好在字符串的末端,但是最后统一i++, j++了,在退出循环后的部分无法识别->flag误判为true)
然后修改为将四个修改语句全放在If里面,此时会导致url_pos和rule_pos会停留上一个 / 的下一个位置无法更新,会导致退出循环后部分无法识别,flag被误判为false)

2 1
/articles// year_archive
/articles/ year_archive2
/articles/2005

缓缓流下泪水,虽然老牛拉车磨了好久,好歹是又做出来了一个第三题…

#include<bits/stdc++.h>
using namespace std;

int n, m;
vector<string> rule_name;
map<string, string> match;

//判断某个字符串是否为阿拉伯数字串
bool matchForInt(string str)
{
    for(int i = 0;i < str.size();i ++){
        if(!(str[i] >= '0' && str[i] <= '9'))
            return false;
    }
    return true;
}
//判断某个字符串是否为合格的字符串
bool matchForString(string str)
{
    for(int i = 0;i < str.size();i ++){
        if(!( (str[i]>='a' && str[i]<='z')||(str[i]>='A' && str[i]<='Z')||(str[i] >= '0' && str[i] <= '9')||str[i] == '-'||str[i] == '_'||str[i] == '.' )){
            return false;
        }
    }
    return true;
}
bool matchForPath(string path)
{
    int pos = 0, i = 0;
    while(i <= path.size() - 1){
        while(path[i] != '/' && i <= path.size() - 1) i ++;

        string str = path.substr(pos, i - pos);

        if(matchForInt(str) || matchForString(str)){
            i ++;
            pos = i;
        }
        else return false;
    }
    return true;
}
bool compare(string p, string q)
{
    if(p.size() != q.size()) return false;
    int i = 0;

    while(i < p.size()) {
        if(p[i] != q[i]) return false;
        i ++;
    }
    return true;
}

bool handle(string url, string rule, int index)
{
    vector<string> wildcard;  //记录所有的通配符
    int rule_pos = 1, url_pos = 1, i = 1, j = 1;
    bool flag = true;

    while(rule_pos <= rule.size() - 1 && url_pos <= url.size() - 1){
        string str1, str2;
        while(url[i] != '/' && i <= url.size() - 1) i ++;
        while(rule[j] !='/'&& j <= rule.size() - 1) j ++;

        str1 = url.substr(url_pos, i - url_pos);
        str2 = rule.substr(rule_pos, j - rule_pos);  //取出两个斜杠之间的内容

        if(str2[0] == '<'){
            //遇到了通配符
            string card = str2.substr(1, str2.size() - 2);

            if(card == "int"){
                flag = matchForInt(str1);

                //删除前缀0
                if(flag){
                    int k = 0;
                    while(str1[k] == '0') k ++;
                    str1 = str1.substr(k, str1.size() - k);
                }
            }else if(card == "str"){
                flag = matchForString(str1);
            }else if(card == "path"){
                str1 = url.substr(url_pos, url.size() - url_pos);
                i = url.size();
                flag = matchForPath(str1);
            }

            if(flag) wildcard.push_back(str1);
        }
        else {
            //不是通配符,比较两个字串是否相等
            flag = compare(str1, str2);
        }

        if(!flag) return flag;  //如果已经有不匹配的了

        if(j <= rule.size() - 1 && i <= url.size() - 1){
            i ++; j ++;
        }
        url_pos = i; rule_pos = j;

    }

    if(rule_pos <= rule.size() - 1 || url_pos <= url.size() - 1)
        return false;  //不完全匹配,url的前半部分与rule匹配

    if(flag) {   //匹配成功
        string key = rule_name[index];
        cout << match[key] << " ";

        for(int k = 0;k < wildcard.size();k ++){
            cout << wildcard[k] << " ";
        }
    }
    return flag;
}

int main()
{
    cin >> n >> m;
    string key, value, url;

    for(int i = 0;i < n;i ++){
        cin >> key >> value;
        rule_name.push_back(key);
        match[key] = value;
    }

    while(m --){
        cin >> url;
        bool finish = false;
        for(int i = 0;i < n;i ++){
            string key = rule_name[i];
            finish = handle(url, key, i);
            if(finish) break;
        }
        if(!finish) cout << "404" << endl;
        else cout << endl;
    }
    return 0;
}

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值