一样的算法。。不一样的效率。请指点!!!!!!!!!!!!!
8皇后的隐身。。理解为n皇后吧。当n=13时我写的程序比标准程序慢很多,可是我们使用的算法时一样的,请明白人指点一下!
我的程序:
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin ("checker.in");
ofstream fou ("checker.out");
int n, solutions = 0;
int cols[15] = {0};
int diagonalUp[ 100 ] = {0};
int diagonalDown[ 100 ] = {0};
int data[ 14] = { 0 },cpyData[14] = {0};
int const excursion = 13;
int counter = 0;
int canPlace( int row, int col )
{
if( cols[col] || diagonalUp[ row + col ] || diagonalDown[ row - col + excursion ] )
return 0;
return 1;
}
void Place( int row, int col )
{
cols[col]++;
diagonalUp[ row + col ]++;
diagonalDown[ row - col + excursion ]++;
data[row] = col;
}
void unPlace( int row, int col )
{
cols[col]--;
diagonalUp[ row + col ]--;
diagonalDown[ row - col + excursion ] --;
data[row] = 0;
}
void work( int row )
{
if( row > n )
{
counter++;
solutions++;
if( counter < 4 )
{
for( int j = 1; j <=n-1; j++ ) fou << data[j] << ' ';
fou << data[ n ] << '\n';
for( int j = 1; j <= n; j++ ) cpyData[j] = data[j];
}
if( n % 2 == 1 && data[1] < n/2+1 || n % 2 == 0 )solutions++;
}
else
{
if( row == 1 )
for( int i = 1; i <= ( n + 1 ) / 2; i++ )
if( canPlace( row, i ) )
{
Place( row,i );
work( row+1, stop );
unPlace( row,i );
}
else ;
else
for( int i = 1; i <= n; i++ )
{
if( canPlace( row, i ) )
{
Place( row, i );
work( row + 1, stop );
unPlace( row,i );sdfg
}
}
}
}
int main()
{
fin >> n;
work( 1 );
if( counter < 3 )
{
for( int j = 1; j<=n; j++ ) cpyData[j] = n-cpyData[j]+1;
for( int j = 1; j<n; j++ ) fou << cpyData[j] << ' ';
fou << cpyData[n] << '\n';
}
fou << solutions << '\n';
}
标准程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAXN 16
int n;
int nsol, nprinted;
char row[MAXN];
FILE *fout;
void
solution() {
int i;
for(i=0; i<n; i++) {
if(i != 0) fprintf(fout, " ");
fprintf(fout, "%d", row[i]+1);
}
fprintf(fout, "\n");
}
/* Keep track of whether there is a checker on each column, and diagonal. */
char col[MAXN]; /* (i, j) -> j */
char updiag[2*MAXN]; /* (i, j) -> i+j */
char downdiag[2*MAXN]; /* (i, j) -> i-j + N */
/*
* Calculate number of ways to place checkers
* on each row of the board starting at row i and going to row n.
*/
void
nway(i, lim) {
int j;
if(i == n) {
nsol++;
if (n > 6 && row[0] < n/2) nsol++;
if (nprinted++ < 3) solution();
return;
}
for(j=0; j<lim; j++){
if(!col[j] && !updiag[i+j] && !downdiag[i-j+MAXN]){
row[i] = j;
col[j]++;
updiag[i+j]++;
downdiag[i-j+MAXN]++;
nway(i+1,n);
col[j]--;
updiag[i+j]--;
downdiag[i-j+MAXN]--;
}
}
}
main(void) {
FILE *fin = fopen("checker.in", "r");
fout = fopen("checker.out", "w");
fscanf(fin, "%d", &n);
nway(0, n>6?(n+1)/2:n);
fprintf(fout, "%d\n", nsol);
exit (0);
}