题目链接: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
*/