답안 #855886

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
855886 2023-10-02T06:39:21 Z vjudge1 Type Printer (IOI08_printer) C++17
100 / 100
96 ms 49980 KB
// Special Judge
// 最开始用的指针模拟,时间复杂度极大
// 换成数组模拟,这个写法记一下
// 一道标准的字典树模板题


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

#define ll long long
#define ull unsigned long long

const int MAX=26;
const int N=25000;

int mpsize=1;  // T当前大小
string ans="";
string s1, longest;
ll n;

void check(){
	printf("\n\n###Flag###\n\n");
}

struct Node{
	int children[MAX];
	bool mark, end;
} T[20*N];  // 字典树

void insert(const string& s){
	int current=0, nxt, digit;  // digit: char转int, current: 使用arr存储的根节点
	for (char now : s){
		digit=now-'a';
		nxt=T[current].children[digit];  // 查找T中该单词第i个字符的位置,有可能没有,返回0
		/*
		这个地方注意一下,缺少一个给T[current].children[digit]赋值的语句,标答用的&引用,所以在修改nxt的时候就直接change了,不用&需要手动调整
		*/
		if (!nxt) nxt=mpsize++;  // 没有这个节点,那么就新建一个,与此同时,nxt指向错误的值,所以重新赋值
		T[current].children[digit]=nxt;
		current=nxt;  // 照常更新
	}
	T[current].end=true;  // 最后一个节点
}

void dfs(int u){
	const Node &current=T[u];
	if (current.end) ans+="P";  // 结束了(dfs终止条件之一)
	int limited=-1;  // 标记是否为最长的那一条
	for (int i=0; i<MAX; i++){  // 26个字符遍历一遍
		int nxt=current.children[i];
		if (!nxt) continue;  // 这个节点不存在
		if (T[nxt].mark){
			limited=i;
		}
		else{
			ans+=i+'a';  // 走
			dfs(nxt);  // 往下走
		}
	}
	if (limited!=-1){  // 搜索中包含最长边
		ans+=limited+'a';  // 现在再来走这条边
		dfs(current.children[limited]);
	}
	ans+='-';  // 退格
}


int main(){
	cin>>n;
	for(int i=0; i<n; i++){
		cin>>s1;  // 输入
		insert(s1);
		if (s1.length() > longest.size()) longest=s1;
	}
	for (int i=0, u=0; i<longest.size(); i++){  // 把最长的进行标记
		u=T[u].children[longest[i]-'a'];
		T[u].mark=true;
	}
	ans.clear();
	dfs(0);
	while(ans.back() == '-'){
		ans.pop_back();  // 可以残留单词	
	} 
	printf("%lld\n", (ll)ans.size());
	for(int i=0; i<ans.size(); i++){
		printf("%c\n", ans[i]);
	}
	return 0;
}

Compilation message

printer.cpp: In function 'int main()':
printer.cpp:75:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   75 |  for (int i=0, u=0; i<longest.size(); i++){  // 把最长的进行标记
      |                     ~^~~~~~~~~~~~~~~
printer.cpp:85:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   85 |  for(int i=0; i<ans.size(); i++){
      |               ~^~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 600 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 1 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1116 KB Output is correct
2 Correct 2 ms 1372 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 3160 KB Output is correct
2 Correct 10 ms 6488 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 7664 KB Output is correct
2 Correct 7 ms 1880 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 32 ms 20212 KB Output is correct
2 Correct 74 ms 42088 KB Output is correct
3 Correct 40 ms 22004 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 26 ms 14572 KB Output is correct
2 Correct 96 ms 49980 KB Output is correct
3 Correct 46 ms 24816 KB Output is correct
4 Correct 72 ms 47080 KB Output is correct