描述:
输入一些单词,对于输入的每个单词,如果已经被存储,则输出字典序相邻的两个单词(若相邻的单词不足,输出空行)。否则存储这个单词。
输入:
若干行,每行一个单词,每个单词仅由小写字母组成。
输出:
若干行单词。
输入样例:
a
b
c
d
a
b
c
d
c
输出样例:
b
a
c
b
d
c
b
d
思路:
这个题我用二叉搜索树做的,有人说用set会非常地简单。
先说我的复杂的做法吧。判断所询问的单词是否储存或添加一个单词,用二叉搜索树都是非常简单的;关键在于输出字典序相邻的单词。
若询问单词有左右孩子,还是很好处理的,左边相邻单词就是左孩子的最右的孩子,右边相邻就是右孩子的最左孩子;
若询问的单词没有左或右孩子,就需要借用一下左旋,右旋的方法,一直转到它有左孩子和右孩子或它成为根,在进行上面的操作。
关于左旋,右旋(记得它是Splay的两种简单操作)图有点复杂,以后再说吧。
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<algorithm> 5 #include<iostream> 6 7 using namespace std; 8 9 struct node 10 { 11 int left,right; 12 int p,pp; 13 string s; 14 node() 15 { 16 left=0;right=0; 17 p=0;pp=0; 18 } 19 }sear[200005]; 20 int cnt,root; 21 22 int que(int num,string ss) 23 { 24 if(sear[num].s==ss)return num; 25 if(ss>sear[num].s) 26 { 27 if(sear[num].right) 28 { 29 return que(sear[num].right,ss); 30 } 31 else 32 { 33 cnt++; 34 sear[num].right=cnt; 35 sear[cnt].s=ss; 36 sear[cnt].p=num; 37 return 0; 38 } 39 } 40 if(ss<sear[num].s) 41 { 42 if(sear[num].left) 43 { 44 return que(sear[num].left,ss); 45 } 46 else 47 { 48 cnt++; 49 sear[num].left=cnt; 50 sear[cnt].s=ss; 51 sear[cnt].pp=num; 52 return 0; 53 } 54 } 55 } 56 57 void rr(int num)//右旋 58 { 59 int tem=sear[num].pp; 60 sear[num].pp=0; 61 if(sear[tem].pp) 62 { 63 int gra=sear[tem].pp; 64 sear[gra].left=num; 65 sear[num].pp=sear[tem].pp; 66 } 67 else 68 { 69 if(sear[tem].p) 70 { 71 int gra=sear[tem].p; 72 sear[gra].right=num; 73 sear[num].p=sear[tem].p; 74 } 75 else 76 { 77 root=num; 78 } 79 } 80 sear[tem].left=sear[num].right; 81 sear[sear[num].right].pp=tem; 82 sear[sear[num].right].p=0; 83 sear[num].right=tem; 84 sear[tem].p=num;sear[tem].pp=0; 85 } 86 void lr(int num)//左旋 87 { 88 int tem=sear[num].p; 89 sear[num].p=0; 90 if(sear[tem].pp) 91 { 92 int gra=sear[tem].pp; 93 sear[gra].left=num; 94 sear[num].pp=sear[tem].pp; 95 } 96 else { 97 if(sear[tem].p) 98 { 99 int gra=sear[tem].p; 100 sear[gra].right=num; 101 sear[num].p=sear[tem].p; 102 } 103 else 104 { 105 root=num; 106 } 107 } 108 sear[tem].right=sear[num].left; 109 sear[sear[num].left].p=tem; 110 sear[sear[num].left].pp=0; 111 sear[num].left=tem; 112 sear[tem].pp=num;sear[tem].p=0; 113 } 114 115 int main() 116 { 117 cnt=0; 118 string ss; 119 while(cin>>ss) 120 { 121 if(cnt==0) 122 { 123 cnt++; 124 sear[cnt].s=ss; 125 root=1; 126 continue; 127 } 128 int weizhi=que(root,ss); 129 if(weizhi) 130 { 131 132 while((!sear[weizhi].left)||(!sear[weizhi].right)) 133 { 134 if(weizhi==root)break; 135 if(sear[weizhi].p)lr(weizhi); 136 else rr(weizhi); 137 } 138 if(sear[weizhi].left) 139 { 140 int tem=sear[weizhi].left; 141 while(sear[tem].right)tem=sear[tem].right; 142 cout<<sear[tem].s; 143 } 144 else { 145 if(sear[weizhi].p!=0) 146 { 147 int tem=sear[weizhi].p; 148 cout<<sear[tem].s; 149 } 150 } 151 cout<<endl; 152 if(sear[weizhi].right) 153 { 154 int tem; 155 tem=sear[weizhi].right; 156 while(sear[tem].left)tem=sear[tem].left; 157 cout<<sear[tem].s; 158 } 159 else { 160 if(sear[weizhi].pp!=0) 161 { 162 int tem=sear[weizhi].pp; 163 cout<<sear[tem].s; 164 } 165 } 166 cout<<endl; 167 } 168 } 169 return 0; 170 }
关于set:
1 #include<set> 2 #include<cstdio> 3 #include<iostream> 4 #include<cstdlib> 5 #include<string> 6 #include<algorithm> 7 8 using namespace std; 9 10 set<string> danci; 11 12 int main() 13 { 14 string ch; 15 set<string>::iterator it1,it2,tem,it; 16 while(cin>>ch) 17 { 18 if(!danci.count(ch))danci.insert(ch); 19 else 20 { 21 tem=danci.find(ch); 22 it=tem; 23 it--; 24 it1=it; 25 it=tem; 26 it++; 27 it2=it; 28 if(tem!=danci.begin()) 29 { 30 cout<<*(it1); 31 } 32 cout<<endl; 33 tem++; 34 if(tem!=danci.end()) 35 { 36 cout<<*(it2); 37 } 38 cout<<endl; 39 } 40 } 41 return 0; 42 }