https://projecteuler.net/problem=393
Fork: https://www.shuizilong.com/house/archives/ural-1519-formula-1/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int hh = 12, ww = 12, _W = 15, MaxH = 10 * 15511;
bool O[hh+1][ww+1]; int A, B, X, Y; int h, w, l, s;
long long ans, d;
struct hashTable {
int state[MaxH], head[MaxH], next[MaxH], sz;
long long key[MaxH];
inline void clear() {
sz = 0;
memset(head, -1, sizeof(head));
}
inline void insert(int s) {
int x = s % MaxH;
for ( int it = head[x] ; it != -1 ; it = next[it] ) {
if ( state[it] == s ) {
key[it] += d;
return;
}
}
state[sz] = s, key[sz] = d;
next[sz] = head[x];
head[x] = sz++;
}
} H[2] , *src , *des;
int n;
inline int countBits(int x){
x = (x & 0x00005555) + ((x & 0x0000aaaa) >> 1);
x = (x & 0x00003333) + ((x & 0x0000cccc) >> 2);
x = (x & 0x00000f0f) + ((x & 0x0000f0f0) >> 4);
x = (x & 0x000000ff) + ((x & 0x0000ff00) >> 8);
return x;
}
int eatLeft(int s, int i){
int An = 0;
for (i--;;i--){
if (!(s & (1 << i))) continue;
if (s & (1 << _W + i)) An++;
else {if (An==0){s ^= 1 << (_W + i); return s;} An--;}
}
}
int eatRight(int s, int i){
int An = 0;
for (i++;;i++){
if (!(s & (1 << i))) continue;
if (!(s & (1 << _W + i))) An++;
else {if (An==0){s ^= 1 << (_W + i); return s;} An--;}
}
}
bool _O(){
for (int i=0;i<w;i++)
if (!O[h-1][i]) return false;
return true;
}
void init(){
h = w = n;
for (int i=0;i<h;i++)
for (int j=0;j<w;j++)
O[i][j] = false;
while (_O()) h--;
for (int i=0;i<h;i++)
O[h][i] = O[i][w] = true;
}
void solve(){
src = H, des = src + 1, d = 1;
des->clear(), des->insert(0); src->clear();
ans = 0;
int _w = w;
for (int i = 0; i < h; i ++){
for (int j = 0; j < src->sz; j ++)
des->state[j] <<= 1;
w = _w;
while (O[i][w-1]) w--;
// cout << w << " " << i << endl;
for (int j = 0; j < w; j ++){
if (O[i][j]) continue;
swap(src, des), des->clear();
// cout << " " << j << endl;
for (int k = 0; k < src->sz; k ++){
s = src->state[k], d = src->key[k];
A = s & (1 << j), B = s & (1 << (j+1));
// cout << " " << k << " " << src->sz << endl;
if (!A && !B){
if (!O[i+1][j] && !O[i][j+1]) des->insert(s ^ (3 << j | 1 <<( _W + j + 1)));
}
else{
X = s & (1 << (_W + j)), Y = s & (1 << (_W + j + 1));
if (A && B){
if (X){
if (Y){ //'))'
des->insert(eatLeft(s, j) ^ (3 << j | 3 << _W + j));
}
else { //')('
des->insert(s ^ (3 << j | 1 << _W + j));
}
}
else {
if (Y){ //'()' if (Y){ //'()'
// ans += d;
d *= 2;
if (i + 1 == h && j + 1 == w && countBits(s)==2) ans += d;
// d *= 2;
// if (
des->insert(s ^ (3 << j) ^ X ^ Y);
d /= 2;
}
else { //'(('
des->insert(eatRight(s, j+1) ^ (3 << j));
}
}
}
else {
if (A){
if (!O[i+1][j]) des->insert(s);
if (!O[i][j+1]) {
if (X) des->insert(s ^ (3 << j | 3 << (_W + j)));
else des->insert(s ^ (3 << j));
}
}
else {
if (!O[i][j+1]) des->insert(s);
if (!O[i+1][j]) {
if (Y) des->insert(s ^ (3 << j | 3 << (_W + j)));
else des->insert(s ^ (3 << j));
}
}
}
}
}
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("/users/xiaodao/desktop/Exercise/in.txt", "r", stdin);
//freopen("/users/xiaodao/desktop/Exercise/out.txt", "w", stdout);
#endif
//freopen("in.txt", "r", stdin);
while (cin >> n){
init(); ans = 0; solve();
cout << ans << endl;
}
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
