在打印出它找到的第一个解决方案后,我想打印下面找到第一个解决方案的时间。
输入N:4
1 3 0 2
时间:0.001秒
然而,当我输入30作为输入时,它会花费异常长时间,就好像它处于无限循环中一样。此外,当我输入31作为输入时,我花了将近15秒,但打印出的时间仅为0.002秒。我想我应该改变时钟函数的位置,但由于代码在打印出第一个解决方案后退出程序,因此我决定将它们放在哪里变得非常棘手。
非常感谢任何帮助。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int put_queens(int column, int size, int* array);
int check_safe(int column, int row, int* array);
void print_sol(int size, int* array);
int main (void){
int size, flag;
int* array;
clock_t t;
printf("Input N: ");
scanf("%d",&size);
array = (int*) calloc(size, sizeof(int));
t = clock();
flag = put_queens(0,size, array);
if(flag){
printf("No solution");
t = clock() - t;
printf("\nTime: %.3fsec",((float)t)/CLOCKS_PER_SEC);
free(array);
}
return 0;
}
int put_queens(int column, int size, int* array){
clock_t t;
t = clock();
int row, flag;
for( row = 0; row < size; row++ ){
if( check_safe(column, row, array) ){
array[column] = row;
if(column == size - 1){
print_sol(size, array);
t = clock()-t;
printf("\nTime: %.3fsec",((float)t)/CLOCKS_PER_SEC);
free(array);
exit (0);
}
else{
put_queens(column + 1, size, array);
}
}
}
if(row == size && column == size - 1){
flag = 1;
}
return flag;
}
int check_safe(int column, int row, int* array){
int index;
for(index = 0; index < column; index++){
if((array[index] == row ) || (abs(array[index]-row)==abs(column - index))){
return 0;
}
}
return 1;
}
void print_sol(int size, int* array){
int column;
for(column = 0; column < size; column++ ){
printf("%3d", array[column]);
}
}
答案 0 :(得分:0)
请参阅以下两个条件和你的for循环:
for( row = 0; row < size; row++ ){
if( check_safe(column, row, array) ){
array[column] = row;
if(column == size - 1){
print_sol(size, array);
t = clock()-t;
printf("\nTime: %.3fsec",((float)t)/CLOCKS_PER_SEC);
free(array);
exit (0);
}
else{
put_queens(column + 1, size, array);
}
}
}
这里在上面,当第一个if条件满足时,它将检查第二个条件if(column == size -1)。如果第一个条件满足但'column'值已经大于'size',则第二个条件将永远不会满足(例如column = 31和size = 30),递归将继续进行,这是长期采用的原因之一在某些情况下的时间。将第二个if条件更正为if(列&gt;大小)。同样来自for循环,你正在递归地调用函数,对于满足第二个if条件和递归几乎无法控制也变得更加关键,因为对于每个递归它有一个for循环而for循环再次递归地调用该方法。想象一下这里发生了什么。由于存在递归调用的限制,操作系统会突然终止该进程,因为您没有看到该程序的任何输出。关于你的时钟,请用一些打印声明来检查它是否正确得到时间。更改逻辑,以便递归不应该永远持续。再见,你想在这里实现什么?