和上一题很像,只需要增加两行就行。。。
还有hash要开小一点。。。。不然会TLE
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
const long long digit[15] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969 };
char maps[13][13];
long long N, M;
// 哈希表
#define LL long long
const int mod = 10007;
struct HASH{
int head[mod+10], E, next[80000];
LL val[10000], cnt[10000];
void init() {
memset(head, -1, sizeof(head));
E = 0;
}
int findhash(LL x) {
return (x%mod + mod)%mod;
}
void add(LL x, LL sum) {
int u = findhash(x);
for(int i = head[u];i != -1;i = next[i]) if(val[i] == x) {
cnt[i] += sum;
return ;
}
val[E] = x;
cnt[E] = sum;
next[E] = head[u];
head[u] = E++;
}
}biao1, biao2;
//
void init(){
memset( maps, 0, sizeof( maps ) );
for( int i = 1; i <= N; i++ ){
scanf( "%s", &maps[i][1] );
}
for( int j = 2; j <= M - 1; j++ ){
maps[N+1][j] = '#';
}
maps[N+1][1] = maps[N+1][M] = '.';
for( int j = 1; j <= M; j++ ){
maps[N+2][j] = '.';
}
N += 2;
}
long long solve(){
int lasti, lastj;
long long ans;
long long code[13];
lasti = -1;
lastj = -1;
int flag = 0;
for( int i = N; i >= 1 && !flag; i-- ){
for( int j = M; j >= 1 && !flag; j-- ){
if( maps[i][j] == '.' ){
lasti = i;
lastj = j;
flag = 1;
break;
}
}
}
if( lasti == -1 ){
return 0;
}
biao1.init();
biao2.init();
biao2.add( 0, 1 );
ans = 0;
for( int i = 1; i <= N; i++ ){
biao1.init();
for( int k = 0; k < biao2.E; k++ ){
long long tid, tsum;
tid = biao2.val[k];
tsum = biao2.cnt[k];
biao1.add( tid * 3, tsum );
}
for( int j = 0; j < M; j++ ){
biao2.init();
for( int k = 0; k < biao1.E; k++ ){
long long tid, tsum;
tid = biao1.val[k];
tsum = biao1.cnt[k];
long long numj, numj1;
numj = ( tid % digit[j+1] ) / digit[j];
numj1 = ( tid % digit[j+2] ) / digit[j+1];
if( maps[i][j+1] == '.' ){
if( numj == 0 && numj1 == 0 ){
long long tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[j] * 1 + digit[j+1] * 2;
if( j + 1 < M ) biao2.add( tt, tsum );
}else if( numj == 0 || numj1 == 0 ){
int temp = numj + numj1;
long long tt = tid + digit[j] * temp - digit[j] * numj - digit[j+1] * numj1;
biao2.add( tt, tsum );
tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[j+1] * temp;
if( j + 1 < M ) biao2.add( tt, tsum );
}else{
if( numj == 1 && numj1 == 1 ){
int temp = 0;
int l;
for( l = j + 2; l <= M; l++ ){
long long ttt = tid % digit[l+1] / digit[l];
if( ttt == 2 ){
if( temp == 0 ){
break;
}else{
temp--;
}
}else if( ttt == 1 ){
temp++;
}
}
if( l <= M ){
long long ttt = tid % digit[l+1] / digit[l];
long long tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[l] * ( 1 - ttt );
biao2.add( tt, tsum );
}
}else if( numj == 2 && numj1 == 2 ){
int temp = 0;
int l;
for( l = j - 1; l >= 0; l-- ){
int ttt = tid % digit[l+1] / digit[l];
if( ttt == 1 ){
if( temp == 0 ){
break;
}else{
temp--;
}
}else if( ttt == 2 ){
temp++;
}
}
if( l >= 0 ){
long long ttt = tid % digit[l+1] / digit[l];
long long tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[l] * ( 2 - ttt );
biao2.add( tt, tsum );
}
}else if( numj == 1 && numj1 == 2 ){
long long tt = tid - digit[j] * numj - digit[j+1] * numj1;
if( i == lasti && j + 1 == lastj && !tt ){
biao2.add( tt, tsum );
ans += tsum;
}
}else{
long long tt = tid - digit[j] * numj - digit[j+1] * numj1;
biao2.add( tt, tsum );
}
}
}else{
if( numj == 0 && numj1 == 0 ){
biao2.add( tid, tsum );
}
}
}
biao1 = biao2;
}
}
return ans;
}
int main(){
while( cin >> N >> M && !( N == 0 && M == 0 ) ){
init();
printf( "%lld\n", solve() );
}
return 0;
}