CCF-CSP_201803(第13次)

1. 跳一跳


//序列处理
/* CCF201803-1 跳一跳 */
#include <iostream>
using namespace std;

int main(){
    int cur, ans = 0, plus = 0;
    //while(~scanf("%d",&cur) && cur)
    while(scanf("%d", &cur) != EOF && cur) {
        ans += cur;
        if(cur == 1){
            plus = 0;
        }else if(cur == 2) {
            ans += plus;
            plus += 2;
        }
    }
    
    printf("%d\n", ans);
    return 0;
}
1 1 2 2 2 1 1 2 2 0
 
22

2. 碰撞的小球


//第一种:简单模拟
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 102;

struct node{
    int pos, id, dir = 1;
};
vector<node> v(MAXN);

int cmp1(const node &a,const node &b){return a.pos < b.pos;}
int cmp2(const node &a,const node &b){return a.id < b.id;}

int main()
{
    int n, l, t;
    
    scanf("%d%d%d", &n, &l, &t);
    v.resize(n+2);
    v[0].pos = 0;
    v[n+1].pos = l;
    for(int i = 1;i <= n; ++i){
        scanf("%d", &v[i].pos);
        v[i].id = i;
    }
    
    sort(v.begin() + 1, v.end() - 1, cmp1);
    
    for(int i = 1;i <= t; ++i){
        for(int j = 1;j <= n; ++j)
            v[j].pos += v[j].dir;
        for(int k = 1;k < n+2; ++k){
            if(v[k-1].pos == v[k].pos){
                v[k-1].dir = - v[k-1].dir;
                v[k].dir = - v[k].dir;
            }
        }
    }
   
    sort(v.begin() + 1, v.end() - 1, cmp2);
    
    for(int i = 1;i <= n; ++i)
        printf("%d ",v[i].pos);
    return 0;
}
//第二种:数学思想
//所有小球看作为无差别小球,即小球碰撞后,可以看做小球继续向原方向运动,直到碰撞到边界
//这样可以得到所有小球无区别的最终位置
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N = 100;

int st[N]; //Record start position.
int ed[N]; //Record end position.
int tmp[N]; 

int main()
{
    //The key indicates the initial position.
    //The value represents the ranking of the initial position.
    map<int,int> mp;
    int n, L, t;
    
    cin >> n >> L >> t;
    for(int i = 0;i < n; ++i){
        int k;
       
        cin >> st[i];
        tmp[i] = st[i];
        k = st[i] + t;
        k = k % (2*L);
        if(k > L) ed[i] = L - k%L;
        else ed[i] = k;
    }
    
    sort(tmp, tmp + n);//Sort the initial position of the ball.
    sort(ed, ed + n); //Sort the last position of the ball.
  
    //The ranking of the initial position is the same as the ranking of the result position.
    for(int i = 0;i < n;i++)
        mp[tmp[i]] = i;
    for(int i = 0;i < n;i++)
        cout << ed[mp[st[i]]] <<" ";
    
    return 0;
}
10 22 30
14 12 16 6 10 2 8 20 18 4

6 6 8 2 4 0 4 12 10 2

3. **** URL映射


#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;

class rule{
public:
    string name;
    vector<string> key;
    rule(string a, vector<string> b) :name(a), key(b) {}
};

vector<rule> rules;
bool isMatch;

int s_to_i(string s){
    int ans;
    stringstream ss(s);
    ss >> ans;
    return ans;
}

string i_to_s(int a){
    stringstream ss;
    ss << a;
    return ss.str();
}

bool judgeNum(string s){
    for (int i = 0; i<s.length(); i++){
        if (s[i]>'9' || s[i]<'0')
            return false;
    }
    return true;
}

void split(string s, string n){
    vector<string> co;
    bool f = true;//Is it a slash
    
    if (s[s.length() - 1] != '/') {
        f = false;
        s = s + "/";
    }
    size_t spi = s.find("/");
    while (spi != -1) {
        string str= s.substr(0, spi);
        s = s.substr(spi + 1, s.length());
        co.push_back(str);
        spi = s.find("/");
    }
    if (f)
        co.push_back("/");
    rules.push_back(rule(n, co));
}

vector<string> match(int k, string u){
    size_t i, j,pos = 0;
    vector<string> result, query;
    bool f = true;//Is it a slash
    
    if (u[u.length() - 1] != '/') {
        f = false;
        u = u + "/";
    }
    
    size_t spi = u.find("/");
    while (spi != -1) {
        string s = u.substr(0, spi);
        u = u.substr(spi + 1, u.length());
        query.push_back(s);
        spi = u.find("/");
    }
    if (f)  query.push_back("/");
    
    
    for (i = 0; i < rules[k].key.size() && pos < query.size(); ++i) {
        if (rules[k].key[i] == "<path>" && query[pos].length() != 0) { // <path> Not empty
            string s = query[pos];
            
            for (j = pos + 1; j < query.size(); ++j) {
                if (query[j] == "/") s = s + "/";
                else s = s + "/" + query[j];
            }
            result.push_back(s);
            pos = query.size(); // <path>  后直接全部作为参数,index指向末尾表示匹配完成
            i = rules[k].key.size();  // <path> 后直接全部作为参数,i指向末尾表示匹配完成
        }
        else if (rules[k].key[i] == "<int>" && query[pos].length() != 0) { // <int> Not empty
            if (judgeNum(query[pos])) {  // 如果待匹配路径为数字(与<int>匹配)
                result.push_back(i_to_s(s_to_i(query[pos])));  // 字符串转数字后再转字符串,去除0
                pos++;
            }else {
                isMatch = false;
                break;
            }
        }
        else if (rules[k].key[i] == "<str>" && query[pos].length() != 0) { // <str> Not empty
            result.push_back(query[pos]);  // <str>
            pos++;
        }
        else { // articles or static
            if (rules[k].key[i] == query[pos])
                pos++;
            else {//End of match
                isMatch = false;
                break;
            }
        }
    }
    if (pos != query.size() || i < rules[k].key.size())// Unmatched
        isMatch = false;
    
    return result;
}

int main()
{
    string rule, name, url;
    int n, m;
    
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        cin >> rule >> name;
        rule = rule.substr(1, rule.length());//rule[0]='/',rule[rule.length()]='/0'
        split(rule, name);
    }
    for (int i = 0; i < m; i++) {
        int k;
        
        cin >> url;
        url = url.substr(1, url.length());
        for (k = 0; k < n; ++k) {
            isMatch = true;
            vector<string> result = match(k, url);
            
            if (isMatch) {
                cout << rules[k].name;
                for (int j = 0; j < result.size(); j++)
                    cout << " " << result[j];
                cout << endl;
                break;
            }
        }
        if (k == n) cout << "404" << endl;
    }
    
    return 0;
}
/* CCF201803-3 URL映射 */
#include <iostream>
#include <ctype.h>

using namespace std;
const int N = 100;
string rUrl[N], nUrl[N];
//Rules for URL matching, Names for URL matching.

bool match(string& adr, string& rule, bool flag)
{
    int rlen =(int) rule.size();
    int alen =(int) adr.size();
    int apos = 0, rpos= 0;
    
    while(apos < alen && rpos < rlen) {
        if(rule[rpos] == adr[apos]) {
            apos++;
            rpos++;
        } else {
            // match <xxx>
            if(rule[rpos++] != '<') return false;
            if(flag) cout << ' ';//Output
            // match <int>
            if(rule[rpos] == 'i') {
                bool ok = false;
                
                while(adr[apos] && isdigit(adr[apos])) {
                    if(adr[apos] != '0')
                        ok = true;
                    if(flag && ok)
                        cout << adr[apos];//Output <int>
                    apos++;
                }
                if(!ok) return false;
                rpos += 4;
            } // match <str>
            else if(rule[rpos] == 's') {
                bool ok = false;
                
                while(adr[apos] && adr[apos] != '/') {
                    ok = true;
                    if(flag)
                        cout << adr[apos];//Output <str>
                    apos++;
                }
                if(!ok)
                    return false;
                rpos += 4;
            } // match <path>
            else if(rule[rpos] == 'p') {
                if(flag){
                    while(adr[apos])
                        cout << adr[apos++];//Output <path>
                }
                return true;
            }
        }
    }
    return rpos == rlen && apos == alen;
}

int main()
{
    int n, m;
    
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        cin >> rUrl[i] >> nUrl[i];
    for(int i = 0; i < m; i++) {
        string aUrl;//URL address
        bool flag = true;
        
        cin >> aUrl;
        for(int j = 0; flag && j < n; j++){//One by one matching URL rules.
            if(match(aUrl, rUrl[j], false)) {
                flag = false;
                
                cout << nUrl[j];//Output name
                match(aUrl, rUrl[j], true);
            }
        }
        
        if(flag) cout << "404";
        cout << endl;
    }
    
    return 0;
}
5 4
/articles/2003/ special_case_2003
/articles/<int>/ year_archive
/articles/<int>/<int>/ month_archive
/articles/<int>/<int>/<str>/ article_detail
/static/<path> 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

4. 棋局评估


//棋局评估(极大极小搜索、博弈论)
//3*3棋盘
//棋局评分
//Alice获胜的棋面:评分(棋盘上的空格数+1)
//bobu获胜的棋面:评分 -(棋盘上的空格数+1)
//平局的棋面:评分 0
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
int mp[4][4];
bool hok(int h,int f){
    return mp[h][0]==f&&mp[h][0]==mp[h][1]&&mp[h][1]==mp[h][2];          //判断行是否三颗相连
}
bool lok(int l,int f){
    return mp[0][l]==f&&mp[0][l]==mp[1][l]&&mp[1][l]==mp[2][l];          //判断列是否三颗相连
}
int spa(){
    int res=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(!mp[i][j])res++;
    return res;
}
int win(int f){                                                          //判断当前局面胜负情况
    int wi=0,ans=1;
    if(hok(0,f)||hok(1,f)||hok(2,f))wi=1;
    if(lok(0,f)||lok(1,f)||lok(2,f))wi=1;
    if(mp[0][0]==f&&mp[0][0]==mp[1][1]&&mp[1][1]==mp[2][2])wi=1;
    if(mp[0][2]==f&&mp[0][2]==mp[1][1]&&mp[1][1]==mp[2][0])wi=1;
    if(!wi)return 0;
    ans+=spa();
    return (f==1)?ans:-ans;
}
int dfs(int peo){                                                        //对抗搜索
    if(!spa())return 0;
    int Max=-10,Min=10;
    for(int i=0;i<3;i++){
        for(int j=0,w;j<3;j++){
            if(!mp[i][j]){                                               //枚举可以落棋的位置
                mp[i][j]=peo+1;
                w=win(peo+1);
                if(w){
                    mp[i][j]=0;
                    return w>0?max(Max,w):min(Min,w);
                }
                if(!peo)Max=max(Max,dfs(1));
                else    Min=min(Min,dfs(0));
                mp[i][j]=0;
            }
        }
    }
    return peo?Min:Max;                                                  //0-Alice-Max,1-Bob-Min
}
int main(){
    #ifdef Mytest
    freopen("in.txt","r",stdin);
    #endif
    int t; //棋局数
    cin>>t;
    while(t--){
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                cin>>mp[i][j];
        int x=win(1),y=win(2);
        if(x){cout<<x<<endl;continue;}
        if(y){cout<<y<<endl;continue;}
        cout<<dfs(0)<<endl;                                              //0表示Alice下,1表示Bob下
    }
    return 0;
}

3
1 2 1
2 1 2
0 0 0
2 1 1
0 2 1
0 0 2
0 0 0
0 0 0
0 0 0
 
3
-4
0

5. 二次求和



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值