Personal programming language Gym - 100741B(dfs)

VJudge竞赛题解析
本文解析了一道VJudge竞赛题目,介绍了如何通过构建图模型来解决字符串递归定义的问题,并给出了具体的C++实现代码。

题目链接:https://vjudge.net/contest/181019#problem/B

题意:定义函数,若 def a = value则a就是value;若def a = valuea  def b with a = valueb则b为valueb valuea;若def a = valuea   def b with a = valueb  def c with b with a = valuec 则因为b中包含a,则在这个串总去掉前面出现的a,只保留最后一个出现的a,即去掉b中的a,保留a中的a,故c为valuec valueb valuea。输入一个串s,求s代表的值,输入保证s一定是def过的。

思路:将每个串与其with的串看做两个点连接起来,查询串s时,已串s为起点,在与其相连的其他串(与其相连的点)中dfs按要求输出即可,vis数组标记一个串是否输出过了。

代码如下:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<sstream>
#include<deque>
#include<stack>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int  maxn = 1e5 + 20;
const int  maxt = 300 + 10;
const int mod = 10;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, -1, 1};
const int Dis[] = {-1, 1, -5, 5};
const int inf = 0x3f3f3f3f;
const int MOD = 1000;
int n, m, k;
map<string, int> id;
map<int, string> value;
bool vis[maxn];
vector<int> g[maxn];
vector<string> ans;
void dfs(int u){
    int len = g[u].size();
    int v;
    for(int i = len - 1; i >= 0; --i){//注意一定要倒着遍历,不然def a = 1 def b = 2 def c with b with a = 3的结果会变成3 1 2;应该是3 2 1
        v = g[u][i];
        if(!vis[v]){
            dfs(v);
            vis[v] = true;
        }
    }
    if(!vis[u]){
        ans.push_back(value[u]);
        vis[u] = true;
    }

}
int main(){
    scanf("%d", &n);
    getchar();
    int cnt = 0;
    bool ok;
    string str, s;
    for(int i = 1; i <= n; ++i){
        getline(cin, str);//一行一行的读
        stringstream ss(str);
        int u;
        while(ss >> s){
            if(s == "def"){
                ss >> s;
                if(id.find(s) == id.end()){
                    id[s] = cnt++;
                }
                u = id[s];
            }
            else if(s == "with") continue;
            else if(s == "="){
                ss >> s;
                value[u] = s;
            }
            else{
                if(id.find(s) == id.end()) id[s] = cnt++;
                g[u].push_back(id[s]);//连边
            }
        }
    }
    cin >> s;
    memset(vis, false, sizeof vis);
    ans.clear();
    dfs(id[s]);//以要查询的串对应的点为起点进行dfs,遍历结果存在ans中
    int len = ans.size();
    for(int i = len - 1; i >= 0; --i){//倒叙输出
        cout << ans[i];
        if(i) printf(" ");
    }
    cout << endl;
    return 0;
}
/*
6
def f1 = world
def f2 = hello
def f3 with f2 with f1 = say
def f4 = please
def f5 with f3 with f4 = dont
def f6 with f3 with f2 = rather

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值