题解 P1738 洛谷的文件夹

AC通道

类似 \(Trie\) 树,如果前缀相同则直接下跳,否则新建节点。但是注意这里的节点所存内容较多,建议离散化后用 \(pair\) 存储,便于配对。

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

template <class T>
inline void read(T &a){
  T x = 0, s = 1;
  char c = getchar();
  while (!isdigit(c)) { if (c == '-') s = -1; c = getchar();}
  while (isdigit(c)){x = (x * 10) + (c ^ '0'); c = getchar();}
  a = x * s;
  return ; 
}

int T;
map<string, int> g;
int top = 0;
vector<int> G;


struct Tree{
  struct node{
    vector< pair<int, int> > H;
  } t[N];
  int ans = 0, p, q;
	
	inline void clean(){
		this->p = 0;
		this->q = 0; 
		return ; 
	}
	
  Tree(){
    this->ans = 0;
    return;
  }

  void main(){ // x 为目标添加编号
    this->p = 0;
    this->q = 0; // 0号作为初始节点
    while (q < G.size()){
      bool flag = 0;
      int now = 0; 
      for (int i = 0; i < t[p].H.size(); i++){
        if (t[p].H[i].first == G[q]){
          flag = 1;
          now = i; 
          break;
        }
      }

      if (flag){
        p = t[p].H[now].second;
        q++;
      }
      else{ // 新建
        t[p].H.push_back(make_pair(G[q], ++ans));
        p = ans;
        q++;
      }
    }
    return ;
  }

} tree;

inline void clean(){
	G.clear();
	tree.clean();
	return ; 
}


int main(){
//	freopen("hh.txt", "r", stdin); 
  read(T);
  while (T--){
    clean(); 
    string s;
    cin >> s;
    int p = 1; // 开头斜杠过滤掉
    string temp = "";
    while (p < s.length()){
      if (s[p] == '/'){ // 分界点
        if (!g[temp])
          g[temp] = ++top;
        p++;
        G.push_back(g[temp]);
        continue;
      }
      temp += s[p];
      p++; 
    }
    if(!g[temp]) g[temp] = ++top;
    G.push_back(g[temp]); 
    tree.main();
    printf("%d\n", tree.ans);
    // 处理完总语句之后
  }
  return 0;
}

posted @ 2022-09-07 21:21  雪之下,树之旁  阅读(22)  评论(0编辑  收藏  举报