• 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 }
  • 相关阅读:
    mysql(二)数据类型
    mysql(一)
    MySQL8 安装官方示例 employees 数据库
    Elasticsearch入门
    redis入门
    git 基本使用
    vue-cli4环境变量配置和代理跨域配置
    nginx配置
    彻底搞清浏览器和服务器跨域
    File文件过滤器
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4731910.html
Copyright © 2020-2023  润新知