URAL_1034
和经典的N皇后问题很相似,尽管N比较大,但由于只重新安排3个皇后有C(N,3)种情况,每个皇后至多有3个位置可以放,所以最大也就是有C(50,3)*3^3种情况。
位运算版的N皇后问题详见Matrix67的博客:http://www.matrix67.com/blog/archives/266。
#include<stdio.h> #include<string.h> #define MAXD 60 int N, cnt, visr[MAXD], visc[MAXD], vis[MAXD][MAXD]; struct Point { int x, y; }p[MAXD]; void init() { int i; memset(vis, 0, sizeof(vis)); for(i = 0; i < N; i ++) { scanf("%d%d", &p[i].x, &p[i].y); vis[p[i].x][p[i].y] = 1; } } int precheck(int x, int y, int z) { int i, j, k; memset(visr, 0, sizeof(visr)); memset(visc, 0, sizeof(visc)); for(i = 0; i < N; i ++) if(i != x && i != y && i != z) { if(visr[p[i].x]) return 0; visr[p[i].x] = p[i].y; if(visc[p[i].y]) return 0; visc[p[i].y] = p[i].x; } } long long cstate() { int i; long long cs = 0; for(i = 1; i <= N; i ++) if(visc[i]) cs |= 1ll << i; return cs; } void dfs(int cur, long long cs, long long ls, long long rs) { int y; long long st; if(cur > N) { ++ cnt; return ; } if(y = visr[cur]) { st = ls | rs; if(st & (1ll << y)) return ; dfs(cur + 1, cs, (ls | (1ll << y)) << 1, (rs | (1ll << y)) >> 1); } else { st = cs | ls | rs; for(y = 1; y <= N; y ++) if((st & (1ll << y)) == 0 && !vis[cur][y]) dfs(cur + 1, cs | (1ll << y), (ls | (1ll << y)) << 1, (rs | (1ll << y)) >> 1); } } void solve() { int i, j, k, p; cnt = 0; for(i = 0; i < N; i ++) for(j = i + 1; j < N; j ++) for(k = j + 1; k < N; k ++) if(precheck(i, j, k)) dfs(1, cstate(), 0, 0); printf("%d\n", cnt); } int main() { while(scanf("%d", &N) == 1) { init(); if(N < 4) printf("0\n"); else solve(); } return 0; }