soj2829binary strings 廣搜

下午閒來無事,突然想起收藏夾裏塵封多年的題目,都是些比較感興趣的題目,隨便看了道2829 binary strings。

大意是:

給定一個初始字符串(不超過20位),和目標字符串,給定操作步驟,求初始字符串到目標字符串的最少操作次數。

操作步驟:對字符串某一段連續區間翻轉(不是按位)

譬如:100011在[1,4]位翻轉->110001

思路:顯然是一個搜索題。狀態映射到數組dist[1<<20]。考慮[i,j],i=j沒有意義,於是每次最多操作有20*19/2=190種,每次都要操作到若干位,按平均10位算大致是1900次,大致3步耗時就比較多了,故用雙向廣搜。

A*算法估價函數不好寫。。。

雙廣注意第一次搜到的結果不一定是最優解!

附代碼如下:

  1. #include <stdio.h>  
  2. #include <ctype.h>  
  3. #include <string.h>  
  4. #include <iostream>  
  5. #include <string>  
  6. #include <math.h>  
  7. #include <vector>  
  8. #include <queue>  
  9.  
  10. using namespace std;  
  11.  
  12. /************************************************************************/ 
  13. /* 雙向廣搜                                                             */ 
  14. /************************************************************************/ 
  15.  
  16. inline bool get(int &t)  
  17. {  
  18.     bool flag = 0 ;  
  19.     char c;  
  20.     while(!isdigit(c = getchar())&&c!='-'if( c == -1 ) break ;  
  21.     if( c == -1 ) return 0 ;  
  22.     if(c=='-') flag = 1 , t = 0 ;  
  23.     else t = c ^ 48;  
  24.     while(isdigit(c = getchar()))    t = (t << 1) + (t << 3) + (c ^ 48) ;  
  25.     if(flag) t = -t ;  
  26.     return 1 ;  
  27. }  
  28.  
  29. #define REP(n) for( i = 0 ; i < n ; i++)  
  30.  
  31. const int maxn = 1 << 20 ;  
  32. int dist[maxn] , len ;  
  33. char st[32] , goal[32] ;  
  34.  
  35. int getValue(char str[])  
  36. {  
  37.     int i , j = 0 ;  
  38.     REP(strlen(str)) j = ( j << 1 ) + ( str[i] ^ 48 ) ;  
  39.     return j ;  
  40. }  
  41.  
  42. int getPos(int i,int j,int key) // i <= j   
  43. {  
  44.     int ii , ans = 0 ;  
  45.     for( ii = i ; ii <= j ; ii++) ans += ( key & ( 1 << ii ) ) ;  
  46.     return ans ;  
  47. }  
  48.  
  49. int getAntiPos(int i,int j,int key) // i <= j   
  50. {  
  51.     int ii , ans = 0 ;  
  52.     int k = i+j ;  
  53.     for( ii = i ; ii <= j ; ii++) ans += ( ( key & ( 1 << ii ) ) > 0 ) ? ( 1 << (k-ii) ) : 0 ;  
  54.     return ans ;  
  55. }  
  56.  
  57. void initArray(int array[])  
  58. {  
  59.     int i ;  
  60.     REP((1<<len)) array[i] = -1 ;  
  61. }  
  62.  
  63. int binSearch()  
  64. {  
  65.     queue<int> head , tail ;  
  66.     head.push(getValue(st)) ;  
  67.     tail.push(getValue(goal)) ;  
  68.     priority_queue<int,vector<int>,greater<int> > ans ;   
  69.     ans.push(0x7fffffff);  
  70.     int i , j , k , kk ;  
  71.     while (1)  
  72.     {  
  73.         int uHead , uTail ;  
  74.         uHead = head.front();    head.pop();  
  75.         uTail = tail.front();    tail.pop();  
  76.         //printf("%d\n",ans.top());  
  77.         if( ans.top() <= (dist[uHead]+((1<<len)^dist[uTail])+1) ) return ans.top();  
  78.         for( i = 0 ; i < len ; i++)  
  79.             for( j = i+1 ; j < len ; j++)  
  80.             {  
  81.                 //reverse[i,j] of head and tail  
  82.                 k = uHead - getPos(i,j,uHead) + getAntiPos(i,j,uHead) ;  
  83.                 kk = uTail - getPos(i,j,uTail) + getAntiPos(i,j,uTail) ;  
  84.                 if( dist[k] >= (1<<len) )      
  85.                 {  
  86.                     ans.push(( dist[k] ^ ( 1 << len ) ) + dist[uHead] + 1 );  
  87.                 }  
  88.                 if( dist[kk] > 0 && dist[kk] < (1<<len) )   
  89.                 {  
  90.                     ans.push( dist[kk] + ( dist[uTail] ^ ( 1 << len ) ) + 1 );  
  91.                 }  
  92.                 if( dist[k] == -1 )   
  93.                 {  
  94.                     dist[k] = dist[uHead] + 1 ;  
  95.                     head.push(k) ;  
  96.                 }  
  97.                 if( dist[kk] == -1 )  
  98.                 {  
  99.                     dist[kk] = dist[uTail] + 1 ;  
  100.                     tail.push(kk) ;  
  101.                 }  
  102.             }  
  103.     }  
  104. }  
  105.  
  106. void solve()  
  107. {  
  108.     len = strlen(st) ;  
  109.     initArray(dist) ;  
  110.     dist[getValue(st)] = 0 ;  
  111.     dist[getValue(goal)] = ( 1 << len ) ;  
  112.     if(getValue(st)==getValue(goal)) puts("0");  
  113.     else    printf("%d\n",binSearch());  
  114. }  
  115.  
  116. int main()  
  117. {  
  118.     int t ;  
  119.     get(t);  
  120.     while (t--)  
  121.     {  
  122.         scanf("%s%s",st,goal);  
  123.         solve();  
  124.     }  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章