soj2829binary strings 广搜

下午闲来无事,突然想起收藏夹里尘封多年的题目,都是些比较感兴趣的题目,随便看了道2829 binary strings。

链接:http://cstest.scu.edu.cn/soj/problem.action?id=2829 

大意是:

给定一个初始字符串(不超过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.     }  

 

你可能感兴趣的:(搜索,soj)