天梯赛补题 - 家谱处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yxm980918/article/details/79614441

这题之前数据结构作业做过,写的好像挺麻烦的,比赛时也没功夫写,今天静下心来倒是想了个不错的方法,无BUG 1A

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>
#include <vector>
#include <map>
#include <sstream>
#define LL long long
const LL INF = 0x3f3f3f3f;
const int maxn = 200000 + 5;
using namespace std;
int fa[maxn];
int a[maxn];
map<string,int> maps;
string s;
vector<int> vec[maxn];
bool dfs(int f, int son){
    if(vec[f].size() == 0)
        return false;
    for(int i=0; i<vec[f].size(); i++){
        if(vec[f][i] == son) return true;
        if(dfs(vec[f][i],son)) return true;
    }
    return false;
}
bool solve(string name1, string name2, string op){
    int id1 = maps[name1];
    int id2 = maps[name2];
    if(op == "child")
        return fa[id1] == id2;
    if(op == "ancestor")
        return dfs(id1,id2);
    if(op == "sibling")
        return fa[id1] == fa[id2];
    if(op == "parent")
        return fa[id2] == id1;
    if(op == "descendant")
        return dfs(id2,id1);
    return false;
}
int main(){
    int cnt = 0, deep, j;
    int n,q;
    string name;
    cin >> n >> q;
    getchar();
    for(int i=0; i<n; i++){
        deep = 0;
        getline(cin,s);
        int len = (int)s.length();
        for(j=0; j<len; j++){
            if(s[j] == ' ') deep++;
            else break;
        }
        name = s.substr(j,len-j);
        maps[name] = cnt++;
        int id = maps[name];//该串的序号
        deep /= 2;
        int turn = a[deep];//此时的父亲
        if(id != 0){
            vec[turn].push_back(id);
            fa[id] = turn;
        }
        else fa[id] = -1;
        a[deep+1] = id;//更新当前层数的父亲
    }
    string x;
    while(q--){
        string name1, name2, judge, temp;
        cin >> name1 >> temp >> temp >> judge >> temp >> name2;
        if(solve(name1,name2,judge)) cout << "True" << endl;
        else cout << "False" << endl;
    }
}

展开阅读全文

没有更多推荐了,返回首页