USACO 1.5.4 checker

// checker.cpp : 定义控制台应用程序的入口点。
//

//#include "stdafx.h"

//参考Matrix67位运算讲稿,n皇后问题位运算版
//n皇后,通过位运算解决n皇后问题,输出所有解的总数和前3组解的具体放置方法

/*
ID: maiyuet1
PROG: checker
LANG: C++
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

int n;
int upperlim;
int cnt;
int save[100];

 //row表示横行放皇后的情况,ld、rd分别是左右对角线的情况,k为第k行
void test(int row, int ld, int rd, int k)
{ 
	if(k == n)  //n皇后全部放完 或者 通过判断row == upperlim
	{
		cnt++;
		//输出前3组解
		if(cnt <= 3)
		{
			for(int i=0; i<n-1; i++)
			{
				cout<<save[i]<<" ";
			}
			cout<<save[n-1]<<endl;
		}
		return ;
	}
	else
	{
		int pos = upperlim & ( ~(row | ld | rd));  //3个方向合并后得到该行所有的禁位,取反得到不冲突的位置
		int p; 
		while(pos != 0)
		{
			p = pos & (~pos + 1); //得到右起第一个"1",即右边第1个不冲突的位置
			pos = pos - p;		//放上这个位置后

			//a = log2(p) + 1;
			if(cnt < 3)
			{
				int a = 1;
				int b = p;
				while(b != 1)
				{
					b = b >> 1;
					a++;
				}
				save[k] = a;
			}
			
			test(row+p, (ld+p)<<1, (rd+p)>>1, k+1);
		}
	}
}

int main()
{
	freopen("checker.in","r",stdin);
	freopen("checker.out","w",stdout);
	while(cin>>n)
	{
		upperlim = (1 << n) - 1;  //初始化upperlim为n皇后都放上的情况
		cnt = 0;
		test(0,0,0,0);
		cout<<cnt<<endl;
	}
	return 0;
}

你可能感兴趣的:(c,Matrix)