zoukankan      html  css  js  c++  java
  • POJ 1739

    楼教主男人八题之一。。。 

    题目大意:

    求从左下角经过所有非障碍点一次到达右下角的方案数

    这里不是求回路,但是我们可以考虑,在最下面一行再增加一行,那么就可以当做求此时左下角到右下角的回路总数,那么就转化成了陈丹琦论文的URAL1519的

    方法了

    但是最后一行添加的格子必须是最后一条直线跑的,也就是除了左下角和右下角中间的点只能有水平方向上的插头

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 
      6 using namespace std;
      7 #define ll long long
      8 const int HASH = 10007;
      9 const int STATE = 1000010;
     10 const int MAXD = 15;
     11 int  n , m , enx , eny;
     12 int code[MAXD] , mp[MAXD][MAXD];
     13 bool flag[MAXD][MAXD];//标记位,标记当前点能否作为最终点
     14 ll ans = 0;
     15 struct HASHMAP{
     16     int head[HASH] , next[STATE] , state[STATE] , size;
     17     ll f[STATE];
     18 
     19     void init(){
     20         size = 0;
     21         memset(head , -1 , sizeof(head));
     22     }
     23 
     24     void push_in(int st , ll sum){
     25         int h = st%HASH;
     26         for(int i = head[h] ; ~i ; i=next[i]){
     27             if(st == state[i]){
     28                 f[i]+=sum;
     29                 return ;
     30             }
     31         }
     32         f[size]=sum;
     33         state[size] = st;
     34         next[size] = head[h];
     35         head[h] = size++;
     36     }
     37 }hashmap[2];
     38 
     39 int num = 0;//记录共有的插头数量
     40 void decode(int *code , int m , int st)
     41 {
     42     num = 0;
     43     for(int i=m ; i>=0 ; i--){
     44         code[i] = st&3;
     45         st>>=2;
     46         if(code[i]) num++;
     47     }
     48 }
     49 
     50 int encode(int *code , int m)
     51 {
     52     int st=0;
     53     for(int i=0 ; i<=m ; i++){
     54         st<<=2;
     55         st |= code[i];
     56     }
     57     return st;
     58 }
     59 
     60 void shift(int *code , int m) //换行,可理解为将最右侧轮廓线换到了下一行的最左侧
     61 {
     62     for(int i=m ; i>=0 ; i--) code[i] = code[i-1];
     63     code[0] = 0;
     64 }
     65 
     66 void dpblank(int i , int j , int cur)
     67 {
     68     int k , left , up;
     69     for(k=0 ; k<hashmap[cur].size ; k++){
     70         decode(code , m , hashmap[cur].state[k]);
     71         left = code[j-1];
     72         up = code[j];
     73       //  cout<<"chatou: "<<i<<" "<<j<<" "<<left<<" "<<up<<endl;
     74         if(!left && !up){
     75             if(mp[i][j+1] && mp[i-1][j]){ //不断向上转移
     76                 code[j-1] = 1 , code[j] = 2;
     77                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
     78             }
     79         }
     80         else if(!left && up){
     81             if(mp[i][j+1]) hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
     82             if(mp[i-1][j]){
     83                 code[j-1] = up , code[j] = 0;
     84                 if(j == m) shift(code , m);
     85                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
     86             }
     87         }
     88         else if(left && !up){
     89             if(mp[i-1][j]){
     90                 if(j == m)  shift(code , m);
     91                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
     92             }
     93             if(mp[i][j+1]){
     94                 code[j-1] = 0 , code[j] = left;
     95                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
     96             }
     97         }
     98         else if(left==1 && up == 1){
     99             int cnt = 1;
    100             for(int v=j+1 ; v<=m ; v++){
    101                 if(code[v]==1)cnt++;
    102                 if(code[v]==2)cnt--;
    103                 if(!cnt){
    104                     code[v]=1;
    105                     break;
    106                 }
    107             }
    108             code[j-1] = code[j] = 0;
    109             if(j == m) shift(code , m);
    110             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
    111         }
    112         else if(left == 2 && up == 2){
    113             int cnt=1;
    114             for(int v=j-2 ; v>=1 ; v--){
    115                 if(code[v]==2)cnt++;
    116                 if(code[v]==1)cnt--;
    117                 if(!cnt){
    118                     code[v]=2;
    119                     break;
    120                 }
    121             }
    122             code[j-1] = code[j] = 0;
    123             if(j == m) shift(code , m);
    124             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
    125         }
    126         else if(left==1 && up==2){
    127             if(i==enx && j==eny) {
    128                 code[j-1] = code[j] = 0;
    129                 if(j == m) shift(code , m);
    130                 hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
    131             }
    132         }
    133         else{
    134             code[j-1]=code[j]=0;
    135             if(j == m) shift(code , m);
    136             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
    137         }
    138     }
    139 }
    140 
    141 void dpblock(int i , int j , int cur)
    142 {
    143     int k , left , up;
    144     for(k=0 ; k<hashmap[cur].size ; k++){
    145         decode(code , m , hashmap[cur].state[k]);
    146         left = code[j-1];
    147         up = code[j];
    148        // cout<<"block: "<<i<<" "<<j<<" "<<left<<" "<<up<<endl;
    149         if(!left && !up){
    150             if(j==m) shift(code , m);
    151             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
    152 
    153         }
    154     }
    155 }
    156 
    157 void dpselect(int i , int j , int cur)
    158 {
    159     int k , left , up;
    160     for(k=0 ; k<hashmap[cur].size ; k++){
    161         decode(code , m , hashmap[cur].state[k]);
    162         left = code[j-1];
    163         up = code[j];
    164         if(left==2 && !up){
    165             code[j-1] = 0 , code[j] = 2;
    166             hashmap[cur^1].push_in(encode(code , m) , hashmap[cur].f[k]);
    167         }
    168     }
    169 }
    170 
    171 char s[MAXD][MAXD];
    172 
    173 void init()
    174 {
    175     for(int i=1 ; i<=n ; i++){
    176         scanf("%s" , s[i]+1);
    177         for(int j=1 ; j<=m ; j++){
    178             mp[i][j] = s[i][j]=='.';
    179         }
    180     }
    181     for(int i=n ; i>=1 ; i--)
    182         for(int j=1 ; j<=m ; j++)
    183             if(mp[i][j]) enx=i , eny=j;
    184     mp[n+1][1] = 1 , mp[n+1][m] = 1;
    185     for(int i=2 ; i<m ; i++) mp[n+1][i] = 2;
    186     n++;
    187     for(int i=1 ; i<=m+1 ; i++) mp[0][i] = 0;
    188     for(int i=0 ; i<=n ; i++) mp[i][m+1] = 0;
    189    /* for(int i=0 ; i<=n ; i++)
    190     {
    191         for(int j=1 ; j<=m+1 ; j++){
    192             cout<<mp[i][j]<<" ";
    193         }
    194         cout<<endl;
    195     }
    196     cout<<enx<<" "<<eny<<endl;*/
    197 }
    198 
    199 ll solve()
    200 {
    201     ans = 0;
    202     int cur = 0;
    203     hashmap[cur].init();
    204     hashmap[cur].push_in(0 , 1);
    205     for(int i=n ; i>=1 ; i--){
    206         for(int j=1 ; j<=m ; j++){
    207             hashmap[cur^1].init();
    208             if(mp[i][j]==1) dpblank(i , j , cur);
    209             else if(mp[i][j]==0) dpblock(i , j , cur);
    210             else dpselect(i , j , cur);
    211             cur^=1;
    212         }
    213 
    214     }
    215     for(int i=0 ; i<hashmap[cur].size ; i++) ans+=hashmap[cur].f[i];
    216     return ans;
    217 }
    218 
    219 int main()
    220 {
    221    // freopen("in.txt" , "r" , stdin);
    222     int cas = 0;
    223     while(scanf("%d%d" , &n , &m) , n+m)
    224     {
    225         init();
    226        // printf("Case %d: ",++cas);
    227         if(n==1 && m==1){
    228             printf("%d
    " , 1);
    229             continue;
    230         }
    231         printf("%I64d
    " , solve());
    232     }
    233     return 0;
    234 }
  • 相关阅读:
    Java实现 LeetCode 343 整数拆分(动态规划入门经典)
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 338 比特位计数
    H264(NAL简介与I帧判断)
    分享一段H264视频和AAC音频的RTP封包代码
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4731910.html
Copyright © 2011-2022 走看看