#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
int position[ 300 ] = { 0 } ,col[ 100 ] = { 0 } ,dig[ 300 ] = { 0 } ,invdig[ 300 ] = { 0 } ,count= 0 ,check[ 100 ] = { 0 } ,thread_count;
pthread_t tid[ 100 ] ;
pthread_mutex_t lock;
struct Posi{
int x;
int y;
int n;
int p_col[ 100 ] ;
int p_dig[ 300 ] ;
int p_invdig[ 300 ] ;
int p_position[ 300 ] ;
int thread_id;
} ;
void nqueen( int n,int row,int n_position[ ] ,int n_col[ ] ,int n_dig[ ] ,int n_invdig[ ] ,int which,int x,int y) {
int i,j;
if ( x! = - 1 && y! = - 1 ) {
n_col[ y] = 1 ;
n_dig[ x- y+ n] = 1 ;
n_invdig[ x+ y] = 1 ;
n_position[ x] = y;
}
if ( row== ( n+ 1 ) ) {
/* for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(n_position[i]==j)
printf("o");
else
printf("x");
}
printf("\n");
}
printf("=========================\n");*/
pthread_mutex_lock( & lock) ;
count++ ;
pthread_mutex_unlock( & lock) ;
return ;
}
else if ( check[ row] == 1 ) {
nqueen( n,row+ 1 ,n_position,n_col,n_dig,n_invdig,which,- 1 ,- 1 ) ;
}
else {
for ( i= 1 ; i<= n; i++ ) {
if ( n_col[ i] == 0 && n_dig[ row- i+ n] == 0 && n_invdig[ i+ row] == 0 ) {
n_col[ i] = 1 ;
n_dig[ row- i+ n] = 1 ;
n_invdig[ i+ row] = 1 ;
n_position[ row] = i;
nqueen( n,row+ 1 ,n_position,n_col,n_dig,n_invdig,which,- 1 ,- 1 ) ;
n_col[ i] = 0 ;
n_dig[ row- i+ n] = 0 ;
n_invdig[ i+ row] = 0 ;
}
}
}
}
void * parallel( void * k) {
struct Posi * get= ( struct Posi* ) k;
nqueen( get- > n,get- > x+ 1 ,get- > p_position,get- > p_col,get- > p_dig,get- > p_invdig,get- > thread_id,get- > x,get- > y) ;
pthread_exit( NULL ) ;
}
int gotoparallel( int n) {
int i,j,k,rc;
struct Posi pos[ 100 ] ;
for ( i= 1 ; i<= n; i++ ) {
if ( check[ i] ! = 1 ) {
for ( j= 1 ; j<= n; j++ ) {
if ( col[ j] == 0 && dig[ i- j+ n] == 0 && invdig[ j+ i] == 0 ) {
for ( k= 1 ; k<= 2 * n; k++ ) {
pos[ thread_count] .p_col [ k] = col[ k] ;
pos[ thread_count] .p_dig [ k] = dig[ k] ;
pos[ thread_count] .p_invdig [ k] = invdig[ k] ;
pos[ thread_count] .p_position [ k] = position[ k] ;
}
pos[ thread_count] .x = i;
pos[ thread_count] .y = j;
pos[ thread_count] .n = n;
pos[ thread_count] .thread_id = thread_count;
rc= pthread_create( & tid[ thread_count] ,NULL ,parallel,( void * ) & pos[ thread_count] ) ;
if ( rc) {
printf ( "ERROR; retrun for pthread_create is %d\n " ,rc) ;
exit ( - 1 ) ;
}
/* if(pthread_join(tid[thread_count],NULL)){
perror("pthread_join");
return 1;
}*/
thread_count++ ;
}
}
break ;
}
}
for ( i= 0 ; i< thread_count; i++ ) {
if ( pthread_join( tid[ thread_count] ,NULL ) ) {
printf ( "thread join error\n " ) ;
}
}
return 0 ;
}
int main ( ) {
int n,m,x,y,i;
thread_count= 0 ;
scanf ( "%d %d" ,& n,& m) ;
for ( i= 0 ; i< m; i++ ) {
scanf ( "%d %d" ,& x,& y) ;
x++ ;
y++ ;
col[ y] = 1 ;
dig[ x- y+ n] = 1 ;
invdig[ y+ x] = 1 ;
check[ x] = 1 ;
position[ x] = y;
}
gotoparallel( n) ;
printf ( "count=%d\n " ,count) ;
return 0 ;
}
I2luY2x1ZGU8c3RkaW8uaD4KI2luY2x1ZGU8c3RkbGliLmg+CiNpbmNsdWRlPHB0aHJlYWQuaD4KaW50IHBvc2l0aW9uWzMwMF09ezB9LGNvbFsxMDBdPXswfSxkaWdbMzAwXT17MH0saW52ZGlnWzMwMF09ezB9LGNvdW50PTAsY2hlY2tbMTAwXT17MH0sdGhyZWFkX2NvdW50OwpwdGhyZWFkX3QgdGlkWzEwMF07CnB0aHJlYWRfbXV0ZXhfdCBsb2NrOwpzdHJ1Y3QgUG9zaXsKICAgIGludCB4OwoJaW50IHk7CglpbnQgbjsKICAgICAgICBpbnQgcF9jb2xbMTAwXTsKCWludCBwX2RpZ1szMDBdOwoJaW50IHBfaW52ZGlnWzMwMF07CglpbnQgcF9wb3NpdGlvblszMDBdOwoJaW50IHRocmVhZF9pZDsKfTsKdm9pZCBucXVlZW4oaW50IG4saW50IHJvdyxpbnQgbl9wb3NpdGlvbltdLGludCBuX2NvbFtdLGludCBuX2RpZ1tdLGludCBuX2ludmRpZ1tdLGludCB3aGljaCxpbnQgeCxpbnQgeSl7CglpbnQgaSxqOwoJaWYoeCE9LTEgJiYgeSE9LTEpewoJCW5fY29sW3ldPTE7CgkJbl9kaWdbeC15K25dPTE7CgkJbl9pbnZkaWdbeCt5XT0xOwoJCW5fcG9zaXRpb25beF09eTsKCX0KCWlmKHJvdz09KG4rMSkpewoJLyoJZm9yKGk9MTtpPD1uO2krKyl7CgkJCWZvcihqPTE7ajw9bjtqKyspewoJCQkJaWYobl9wb3NpdGlvbltpXT09aikKCQkJCQlwcmludGYoIm8iKTsKCQkJCWVsc2UgCgkJCQkJcHJpbnRmKCJ4Iik7CgkJCX0KCQkJcHJpbnRmKCJcbiIpOwoJCX0KCQlwcmludGYoIj09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpOyovCgkJcHRocmVhZF9tdXRleF9sb2NrKCZsb2NrKTsKCQljb3VudCsrOwoJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZsb2NrKTsKCQlyZXR1cm47Cgl9CgllbHNlIGlmKGNoZWNrW3Jvd109PTEpewoJCW5xdWVlbihuLHJvdysxLG5fcG9zaXRpb24sbl9jb2wsbl9kaWcsbl9pbnZkaWcsd2hpY2gsLTEsLTEpOwoJfQoJZWxzZXsJCQoJCWZvcihpPTE7aTw9bjtpKyspewoJCQlpZihuX2NvbFtpXT09MCAmJiBuX2RpZ1tyb3ctaStuXT09MCAmJiBuX2ludmRpZ1tpK3Jvd109PTApewoJCQkJbl9jb2xbaV09MTsKCQkJCW5fZGlnW3Jvdy1pK25dPTE7CgkJCQluX2ludmRpZ1tpK3Jvd109MTsKCQkJCW5fcG9zaXRpb25bcm93XT1pOwoJCQkJbnF1ZWVuKG4scm93KzEsbl9wb3NpdGlvbixuX2NvbCxuX2RpZyxuX2ludmRpZyx3aGljaCwtMSwtMSk7CgkJCQluX2NvbFtpXT0wOwoJCQkJbl9kaWdbcm93LWkrbl09MDsKCQkJCW5faW52ZGlnW2krcm93XT0wOwoJCQl9CgkJfQoJfQp9CnZvaWQgKnBhcmFsbGVsKHZvaWQgKmspewoJc3RydWN0IFBvc2kgKmdldD0oc3RydWN0IFBvc2kqKWs7CglucXVlZW4oZ2V0LT5uLGdldC0+eCsxLGdldC0+cF9wb3NpdGlvbixnZXQtPnBfY29sLGdldC0+cF9kaWcsZ2V0LT5wX2ludmRpZyxnZXQtPnRocmVhZF9pZCxnZXQtPngsZ2V0LT55KTsKCXB0aHJlYWRfZXhpdChOVUxMKTsgCn0KaW50IGdvdG9wYXJhbGxlbChpbnQgbil7CglpbnQgaSxqLGsscmM7CglzdHJ1Y3QgUG9zaSBwb3NbMTAwXTsKCWZvcihpPTE7aTw9bjtpKyspewoJCWlmKGNoZWNrW2ldIT0xKXsKCQkJZm9yKGo9MTtqPD1uO2orKyl7CgkJCQlpZihjb2xbal09PTAgJiYgZGlnW2ktaituXT09MCAmJiBpbnZkaWdbaitpXT09MCl7CgkJCQkJZm9yKGs9MTtrPD0yKm47aysrKXsKCQkJCQkJcG9zW3RocmVhZF9jb3VudF0ucF9jb2xba109Y29sW2tdOwoJCQkJCQlwb3NbdGhyZWFkX2NvdW50XS5wX2RpZ1trXT1kaWdba107CgkJCQkJCXBvc1t0aHJlYWRfY291bnRdLnBfaW52ZGlnW2tdPWludmRpZ1trXTsKCQkJCQkJcG9zW3RocmVhZF9jb3VudF0ucF9wb3NpdGlvbltrXT1wb3NpdGlvbltrXTsKCQkJCQl9CgkJCQkJcG9zW3RocmVhZF9jb3VudF0ueD1pOwoJCQkJCXBvc1t0aHJlYWRfY291bnRdLnk9ajsKCQkJCQlwb3NbdGhyZWFkX2NvdW50XS5uPW47CgkJCQkJcG9zW3RocmVhZF9jb3VudF0udGhyZWFkX2lkPXRocmVhZF9jb3VudDsKCQkJCQlyYz1wdGhyZWFkX2NyZWF0ZSgmdGlkW3RocmVhZF9jb3VudF0sTlVMTCxwYXJhbGxlbCwodm9pZCopJnBvc1t0aHJlYWRfY291bnRdKTsKCQkJCQlpZihyYyl7CgkJCQkJCXByaW50ZigiRVJST1I7IHJldHJ1biBmb3IgcHRocmVhZF9jcmVhdGUgaXMgJWRcbiIscmMpOwoJCQkJCQlleGl0KC0xKTsKCQkJCQl9CgkJCS8qCQlpZihwdGhyZWFkX2pvaW4odGlkW3RocmVhZF9jb3VudF0sTlVMTCkpewoJCQkJCQlwZXJyb3IoInB0aHJlYWRfam9pbiIpOwoJCQkJCQlyZXR1cm4gMTsKCQkJCQl9Ki8KCQkJCQl0aHJlYWRfY291bnQrKzsKCQkJCX0KCQkJfQoJCQlicmVhazsKCQl9Cgl9Cglmb3IoaT0wO2k8dGhyZWFkX2NvdW50O2krKyl7CgkJaWYocHRocmVhZF9qb2luKHRpZFt0aHJlYWRfY291bnRdLE5VTEwpKXsKCQkJcHJpbnRmKCJ0aHJlYWQgam9pbiBlcnJvclxuIik7CgkJfQoJfQoJcmV0dXJuIDA7Cn0KCmludCBtYWluICgpewoJaW50IG4sbSx4LHksaTsKCXRocmVhZF9jb3VudD0wOwoJc2NhbmYoIiVkICVkIiwmbiwmbSk7Cglmb3IoaT0wO2k8bTtpKyspewoJCXNjYW5mKCIlZCAlZCIsJngsJnkpOwoJCXgrKzsKCQl5Kys7CgkJY29sW3ldPTE7CgkJZGlnW3gteStuXT0xOwoJCWludmRpZ1t5K3hdPTE7CgkJY2hlY2tbeF09MTsJCgkJcG9zaXRpb25beF09eTsKCX0KCWdvdG9wYXJhbGxlbChuKTsKCXByaW50ZigiY291bnQ9JWRcbiIsY291bnQpOwoJcmV0dXJuIDA7Cn0K