原题地址
http://codeup.hustoj.com/problem.php?cid=100000613&pid=1
解题思路
基本和上一篇方法一样~
注意事项
读入数据的时候注意按照字符串读进来,我一开始直接按照数字读,然后就相当于一行只读进来了一个数字~
参考代码
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
const int inf = 2e9;
const LL INF = 8e18;
const int maxn = 5e5 + 5;
string s;
struct node{
int data;
node* lchild;
node* rchild;
int flag; //标记结点是否访问过,访问过为1
};
//这里要改变指针变量,所以要用引用!!
void insert(node* &root, int v) {
if (!root) {
root = new node;
root->data = v;
root->flag = 0;
root->lchild = root->rchild = NULL;
return;
}
if (v == root->data) return;
if (v < root->data) insert(root->lchild, v);
else insert(root->rchild, v);
}
node* create(int n) {
node* root = NULL;
int i, v;
for (i = 0; i < n; ++i) {
insert(root, s[i] - '0');
}
return root;
}
/*
判别方法:
转化为查找待判断序列中的数
若查找某个数的过程中,路径上的数有未访问过的,则不一致
否则一致
*/
int check(node* t, int v) {
//若该结点是访问过的
if (t->flag) {
if (v < t->data) return check(t->lchild, v);
else if (v > t->data) return check(t->rchild, v);
//若有重复值,代表不一致
else return 0;
}
//若该结点还未访问过
else {
//正好是要查找的结点
if (v == t->data) {
t->flag = 1;
return 1;
}
//若遇到未访问过的结点,又不是要查找的,则代表不一致
else return 0;
}
}
//判别每个元素是否一致
int judge(node* t, int n) {
int i, v;
bool flag = true;
cin >> s;
//先判断树根是否一致
if (s[0] - '0' != t->data) flag = false;
else t->flag = 1;
for (i = 1; i < n; ++i) {
if (flag && (!check(t, s[i] - '0'))) flag = false;
}
if (flag) return 1;
else return 0;
}
//清除t中各结点的flag标记
void reset(node* t) {
if (t->lchild) reset(t->lchild);
if (t->rchild) reset(t->rchild);
t->flag = 0;
}
//释放t的空间
void freeT(node* t) {
if (t->lchild) freeT(t->lchild);
if (t->rchild) freeT(t->rchild);
delete t;
}
int main() {
int n, k;
while (~scanf("%d", &k)) {
if (k == 0) break;
cin >> s;
n = s.size();
node* t = create(n);
while (k--) {
if (judge(t, n)) printf("YES\n");
else printf("NO\n");
reset(t);
}
freeT(t);
}
return 0;
}