ACM-Checker Challenge
1
解题思路:N皇后问题,一般的DFS会超时,用位运算才可以A。
////// Checker Challenge.cpp : 定义控制台应用程序的入口点。 ////// //// #include "stdafx.h" //// //// ////#include <stdio.h> ////#include <math.h> ////#include <string.h> //// ////int n, ans; ////int res[15],save[15]; //// ////struct R ////{ //// int r[15][15]; //// ////}R[15]; //// ////void DFS(int i) ////{ //// if (i == n) //// { //// ans++; //// if (ans <= 3) //// { //// memcpy(R[n].r[ans-1], res, sizeof(res)); //// } //// return; //// } //// //// for (int k = 0; k < n; k++)//遍历所有列 //// { //// int j; //// for (j = 0; j < i; j++)//和已经放好的皇后位置比较 //// { //// if (k == res[j]) break; //// if (abs(k - res[j]) == i - j) break; //// } //// if (j >= i) //// { //// res[i] = k; //// DFS(i + 1); //// } //// } ////} //// ////int main() ////{ //// for (n = 0; n <= 13; n++) //// { //// ans = 0; //// DFS(0); //// save[n] = ans; //// //// } //// while (scanf("%d",&n)!=EOF) //// { //// //// for (int j = 0; j < 3; j++) //// { //// for (int i = 0; i < n; i++) //// { //// if (i != n-1) printf("%d ", R[n].r[j][i] + 1); //// //// else printf("%d\n", R[n].r[j][i] + 1); //// } //// } //// printf("%d\n", save[n]); //// //// } ////} //简化的思想: //用位运算代替for循环遍历每个皇后的位置 //用垂直、对角线、斜对角线的位运算 /*整个逻辑: //1.求将要放入皇后的位置 //2.更新可放皇后的位置 //3.DFS循环*/ #include <stdio.h> int n,ans,uplimit,res[15]; int binary2(int num) { int ans = 0; while (num) { num = num >> 1; ans++; } return ans; } void DFS(int i,int vertical, int diagonal, int antidiagonal) { if (i >= n) { ans++; if (ans <=3) { //输出结果 for (int i = 0; i < n; i++) { if (i != n-1) printf("%d ", res[i]); else printf("%d\n", res[i]); } } return; } int avail = uplimit & (~(vertical | diagonal | antidiagonal)); while (avail) { int pos = avail & (-avail); avail = avail - pos; res[i] = binary2(pos); DFS(i + 1,vertical + pos, (diagonal + pos) << 1, (antidiagonal + pos) >> 1); } } int main() { while (scanf("%d", &n) != EOF) { ans = 0; uplimit = (1 << n) - 1; DFS(0, 0, 0, 0); printf("%d\n", ans); } return 0; }