UVAL - 6755 - Swyper Keyboard

先上題目: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 }
/*6755*/
相關文章
相關標籤/搜索