题目有句话是不希望走更长的路,应该就是哈密尔顿回路了?然后总数乘个2?
还要注意n=1或m=1的时候并没有回路的情况。。
我太弱了,COGS上看到有人说76行即可AC,我写了个99行的。。
不过bzoj上排Rank 61。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 20001, M = 5001;
typedef long long ll;
const int power = 10000;
struct BigInteger {
int c[10], l;
BigInteger(){l=0;memset(c,0,sizeof c);}
BigInteger(int a){memset(c,0,sizeof c);for(l=0;a;a/=power)c[l++]=a%power;}
void out(){printf("%d",c[l-1]);for(int i=l-2;i>=0;i--)printf("%04d",c[i]);}
BigInteger &operator+=(BigInteger b) {
for(l=0;l<b.l;++l) {
c[l] += b.c[l];
c[l + 1] += c[l] / power;
c[l] %= power;
}
for(;c[l];++l) if (c[l] >= power) {
c[l + 1] += c[l] / power;
c[l] %= power;
}
return *this;
}
};
typedef map<ll, BigInteger>::iterator mll;
const int state[] = {0, -1, 1, 0};
int get_bit(int sta, int i) { return (sta >> (i << 1)) & 3; }
int set_bit(int &sta, int i, int x) {
sta = (sta & ~(3 << (i << 1))) | (x << (i << 1));
}
int bracket(int sta, int i, int b) {
int ret = i;
for (int cnt = b; cnt; cnt += state[get_bit(sta, ret)]) ret -= b;
return ret;
}
int left(int sta, int i) { return bracket(sta, i, state[2]); }
int right(int sta, int i) { return bracket(sta, i, state[1]); }
map<ll, BigInteger> hash[2], *cur, *last;
int bx, by, n, m;
char mp[16][16];
void update(int x, int y, int sta, const BigInteger &v) {
int l = y == 0 ? 0 : get_bit(sta, y), s;
int t = x == 0 ? 0 : get_bit(sta, y + 1);
#define create(i,j) s=sta,set_bit(s,y,i),set_bit(s,y+1,j),(*cur)[s]+=v
if (!l && !t) {
if (x != n - 1 && y != m - 1) create(1, 2);
} else if (!l || !t) {
if (x < n - 1) create(l + t, 0);
if (y < m - 1) create(0, l + t);
} else {
s = sta; set_bit(s, y, 0); set_bit(s, y + 1, 0);
if (l == 1 && t == 1) set_bit(s, right(s, y + 1), 1);
else if (l == 1 && t == 2) { if (x != bx || y != by) return; }
else if (l == 2 && t == 1);
else if (l == 2 && t == 2) set_bit(s, left(s, y + 1), 2);
(*cur)[s]+=v;
}
}
BigInteger solve() {
int sz, i, j, rate;
cur = hash; last = hash + 1;
last->clear(); (*last)[0] = 1;
for(i=0;i<n;++i) {
rate = 2;
for(j=0;j<m;++j) {
cur->clear();
for(mll k=last->begin();k!=last->end();++k) {
if (rate == 2 && get_bit(k->first, m)) continue;
update(i, j, k->first << rate, k->second);
}
rate = 0; swap(cur, last);
}
}
BigInteger ans = 0;
for(mll k=last->begin();k!=last->end();++k)
if (k->first == 0) { ans = k->second; break; }
return ans;
}
int main() {
scanf("%d%d", &m, &n);
if (m > n) swap(m, n);
if (m == 1) puts("1");
else {
bx = n - 1, by = m - 1;
BigInteger bi = solve();
bi += bi;
bi.out();
}
return 0;
}