日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【广搜】Keyboarding

發布時間:2024/7/5 编程问答 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【广搜】Keyboarding 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

給定一個r行c列的在電視上的“虛擬鍵盤”,通過“上,下,左,右,選擇”共5個控制鍵,你可以移動電視屏幕上的光標來打印文本。一開始,光標在鍵盤的左上角,每次按方向鍵,光標總是跳到下一個在該方向上與當前位置不同的字符,若不存在則不移動。每次按選擇鍵,則將光標所在位置的字符打印出來。
現在求打印給定文本(要在結尾打印換行符)的最少按鍵次數。

?

輸入

第一行輸入 r,c。
接下來給出一個 r×c的鍵盤,包括大寫字母,數字,橫線以及星號(星號代表 Enter 換行)。
最后一行是要打印的文本串 S,S 的長度不超過 10000。

?

輸出

輸出打印文本(包括結尾換行符)的最少按鍵次數。保證一定有解。

?

樣例輸入

2 19 ABCDEFGHIJKLMNOPQZY X*****************Y AZAZ

樣例輸出

19

?

提示

對于100%的數據,1≤r,c≤50,S的長度不超過10000。

?



?

【題解】

這個題目需要大家耐心處理細節,預處理所有點的四個方向能到達的地方。

然后用BFS搜索,注意搜索的順序,已經利用好vis標記數組來記錄。

?這個題目是真的需要小心,很多坑。

需要設定一個結構體,這個結構體需要提供記錄? 當前的坐標(x,y),匹配到下標 step,當前結點的花費的操作次數 dis

1、預處理所有位置的四個方向的下一個位置是什么?

2、設置標準的BFS框架,其中入隊列之前,可以預處理左上角就是目標串的字符。

3、進入BFS框架時需要兩部分,一個是選擇,另一個是四個方向遍歷,充分要利用vis數組來更新最優值

?

1 #pragma GCC optimize("Ofast") //編譯環境優化 2 #include<bits/stdc++.h> 3 using namespace std; 4 const int N = 52 ; 5 const int M = 1e5+10; 6 const int P = 300; 7 char s[M]; 8 int n,m,len; 9 int Map[P],vis[N][N]; 10 int a[N][N],b[M]; 11 typedef struct Node{ 12 int x,y,step,dis; 13 }Node ; 14 Node F[N][N][4]; 15 16 int dir[4][2]={ 17 {-1,0}, 18 {0,-1},{0,1}, 19 {1,0} 20 }; 21 void read_Char(char s[]){ 22 int len = 0 ; 23 char c = getchar() ; 24 while ( c!='\n' ){ 25 s[len++] = c; 26 c = getchar(); 27 } 28 s[len] = '\0'; 29 } 30 void _Map(){ 31 for(int i=0;i<=9;i++){ 32 Map[char('0'+i)] = i+1; 33 } 34 for (int i=0;i<26;i++){ 35 Map[char('A'+i)] = i+11; 36 } 37 Map['-'] = 37 ; 38 Map['*'] = 38 ; 39 } 40 //預處理,處理每一個方向能到達的位置 41 void Init(){ 42 for(register int i=1;i<=n;i++){ 43 for(register int j=1;j<=m;j++){ 44 for(register int k=0;k<4;k++){ 45 int tx = i,ty = j ; 46 while( a[i][j] == a[tx+dir[k][0]][ty+dir[k][1]] ) 47 tx += dir[k][0] , ty += dir[k][1]; 48 F[i][j][k] = (Node) {tx,ty,0,0}; 49 } 50 } 51 } 52 } 53 int BFS(){ 54 55 memset(vis,0,sizeof(vis)); 56 int k = 1 ; 57 //處理左上角就是目標的輸出 58 while ( a[1][1] == b[k] && k<=len ) k++ ; 59 queue <Node> Q; 60 Q.push( (Node){1,1,k,k-1} ) ; 61 vis[1][1] = k ; 62 while( !Q.empty() ){ 63 64 Node cur = Q.front(); 65 //printf("(%d,%d)\n",cur.x,cur.y); 66 Q.pop(); 67 //如果找到合適的位置則"選擇" 68 if( a[cur.x][cur.y] == b[cur.step] ){ 69 if( cur.step == len ){ 70 return cur.dis + 1 ; 71 } 72 vis[cur.x][cur.y] = cur.step + 1 ; 73 Q.push( (Node) { cur.x,cur.y,cur.step+1,cur.dis+1} ) ; 74 continue ; 75 } 76 //四個方向 77 for(int i=0;i<4;i++){ 78 Node Next = F[cur.x][cur.y][i] ; 79 Next.x += dir[i][0]; 80 Next.y += dir[i][1]; 81 82 if( !(1<=Next.x && Next.x<=n && 1<=Next.y && Next.y<=m) ){ 83 continue; 84 } 85 //if( a[cur.x][cur.y] == a[Next.x][Next.y] ) continue; 86 // 如果后面剪枝過的 87 if( vis[Next.x][Next.y] >= cur.step ) continue ; 88 vis[Next.x][Next.y] = cur.step ; 89 Q.push((Node){Next.x,Next.y,cur.step,cur.dis+1} ); 90 } 91 } 92 } 93 int main() 94 { 95 _Map(); 96 //while( cin >> n >> m ){ 97 while(~scanf("%d%d",&n,&m)){ 98 //memset(a,'\0',sizeof(a)); 99 for(register int i=1;i<=n;i++){ 100 scanf("%s",s+1); 101 //cin >> s+1 ; 102 for(register int j=1;j<=m;j++){ 103 a[i][j] = Map[s[j]]; 104 } 105 } 106 scanf("%s",s+1); 107 //cin >> s+1 ; 108 len = strlen(s+1); 109 for(register int i=1;i<=len;i++){ 110 b[i] = Map[s[i]]; 111 } 112 b[++len] = Map['*']; 113 Init(); 114 printf("%d\n",BFS()); 115 //cout << BFS() << endl; 116 } 117 return 0; 118 } 119 /* 120 2 19 121 ABCDEFGHIJKLMNOPQZY 122 X*****************Y 123 AZAZ 124 */ Keyboarding

?

?

轉載于:https://www.cnblogs.com/Osea/p/11215807.html

總結

以上是生活随笔為你收集整理的【广搜】Keyboarding的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。