先上題目:ios
https://icpcarchive.ecs.baylor.edu/external/67/6755.pdfide
題目複製起來比較麻煩。spa
題意:定義一種操做:給出一個字符串,而後手指就按照給出的字符串的字符出現順序不離開觸摸屏那樣移動,這樣最後就會獲得一個字符串(不必定等於給出的字符串),如今再給你一堆字符串,問你這些字符串根據給你的順序,最早出現的是哪個字符串是獲得的那個字符串的子序列。若是沒有出現的話就輸出"NO SOLUTION"。code
作法:先求出那個字符串,而後再逐個逐個字符串找。關於怎樣求這個字符串,提及來好像有點複雜,大概的作法就是在判斷劃過某兩個字符的過程當中會有哪些字符的時候,先縮小枚舉的範圍,而後對於範圍裏面的每個字符都進行一次判斷,判斷的方法是使用叉積來判斷,若是這個判斷的字符的四個角不都在原來的那兩個字符連成的線段的一側的話說明就是穿過的(注意恰好在線上的狀況)。具體實現看代碼。blog
上代碼:ci
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #include <iostream> 6 #include <string> 7 #define APH 26 8 #define MAX 1002 9 using namespace std; 10 11 12 typedef struct Point{ 13 int x,y; 14 15 Point(int x=0,int y=0):x(x),y(y){} 16 17 }Point; 18 typedef Point Vector; 19 Vector operator + (Point A,Point B){ return Vector(B.x+A.x,B.y+A.y);} 20 Vector operator - (Point A,Point B){ return Vector(B.x-A.x,B.y-A.y);} 21 Vector operator * (Point A,int e){ return Point(A.x*e,A.y*e);} 22 Vector operator / (Point A,int e){ return Point(A.x/e,A.y/e);} 23 24 int Dot(Vector A,Vector B){ return A.x*B.x + A.y*B.y;} 25 inline int Cross(Vector A,Vector B){ return A.x*B.y - A.y*B.x;} 26 27 int cx[]={-1,1,1,-1}; 28 int cy[]={1,1,-1,-1}; 29 30 string path[APH][APH]; 31 Point pos[APH]; 32 char ch[APH][APH]; 33 34 Point getPoint(char c){ 35 if(c<='E') return Point(c-'A'+2,4); 36 else{ 37 return Point((c-'F')%7+1,3-(c-'F')/7); 38 } 39 } 40 41 bool check(Point A,Point B,Point C){ 42 bool b=0,l=0; 43 A.x*=2; A.y*=2; 44 B.x*=2; B.y*=2; 45 C.x*=2; C.y*=2; 46 Point u; 47 for(int i=0;i<4;++i){ 48 u=Point(C.x+cx[i],C.y+cy[i]); 49 if(Cross(A-u,B-u)>0) b|=1; 50 if(Cross(A-u,B-u)<0) l|=1; 51 } 52 return b&&l; 53 } 54 55 string GetPath(int a,int b){ 56 string ans=""; 57 if(a==b) return ans; 58 int ax=pos[a].x,ay=pos[a].y; 59 int bx=pos[b].x,by=pos[b].y; 60 for(int i= ax ; (ax < bx ? i<=bx : i>=bx) ; (ax < bx ? i++ : i--) ){ 61 for(int j= ay ; (ay < by ? j<=by : j>=by) ; (ay < by ? j++ : j--)){ 62 if(ch[i][j]==0) continue; 63 if(check(pos[a],pos[b],pos[ch[i][j]-'A'])) ans+=ch[i][j]; 64 } 65 } 66 //if(ans.length()<=1) return ""; 67 ans = ans.substr(1,max((int)(ans.length()-2),0)); 68 //cout<<ans<<endl; 69 return ans; 70 } 71 72 void prepare(){ 73 memset(ch,0,sizeof(ch)); 74 for(int i=0;i<APH;i++){ 75 pos[i]=getPoint('A'+i); 76 ch[pos[i].x][pos[i].y]='A'+i; 77 // cout<<ch[pos[i].x][pos[i].y]<<" "; 78 } 79 // cout<<endl; 80 for(int i=0;i<APH;i++){ 81 for(int j=0;j<APH;j++){ 82 path[i][j]=GetPath(i,j); 83 // cout<<path[i][j]<<endl; 84 } 85 } 86 } 87 88 string connect(string st){ 89 string ans; 90 ans+=st[0]; 91 for(unsigned int i=1;i<st.length();i++){ 92 ans+=path[st[i-1]-'A'][st[i]-'A']; 93 ans+=st[i]; 94 } 95 //ans+=st[st.length()-1]; 96 return ans; 97 } 98 99 bool check_str(string s,string str){ 100 unsigned i,j; 101 for(i=0,j=0;i<s.length();i++){ 102 if(s[i]==str[j]){ 103 j++; 104 if(j==str.length()) return 1; 105 } 106 } 107 return 0; 108 } 109 110 int main() 111 { 112 int t,n; 113 string st,s,str; 114 //freopen("data.txt","r",stdin); 115 ios::sync_with_stdio(false); 116 prepare(); 117 cin>>t; 118 while(t--){ 119 cin>>n>>st; 120 s=connect(st); 121 //cout<<"* "<<s<<endl; 122 bool f=0; 123 for(int i=0;i<n;i++){ 124 cin>>str; 125 //cout<<str<<endl; 126 if(!f && check_str(s,str)){ 127 f=1; 128 cout<<str<<endl; 129 } 130 } 131 if(!f) cout<<"NO SOLUTION"<<endl; 132 } 133 return 0; 134 }