0表示没有路,当然也不能在一条右斜线上9159.c

作者: 编程  发布:2019-08-29

    八皇后是一道很具典型性的题目。它的基本要求是这样的:在一个8*8的矩阵上面放置8个物体,一个矩阵点只允许放置一个物体,任意两个点不能在一行上,也不能在一列上,不能在一条左斜线上,当然也不能在一条右斜线上。

  

}

    选择排序是和冒泡排序差不多的一种排序。和冒泡排序交换相连数据不一样的是,选择排序只有在确定了最小的数据之后,才会发生交换。怎么交换呢?我们可以以下面一组数据作为测试:

 

 初看到这道题目,大家的第一印象是遍历,但是经过实践之后发现遍历其实不好写,而且复杂度很低。不仅需要遍历8*8*8*8*8*8*8*8*8

2^24次数据,还要判断各种条件,实际的计算复杂度还要比较这个高。其实我们仔细看一看,这中间很多的计算其实很多是不需要的,因为如果我们在某一行没 有可以插入的数据的话,那么这后面的行其实就不用考虑了。也就是说,我们只有在保证前面 插入的物体都合法有效的情况下,才能进行下一次的物体插入。无谓的遍历只会是无用功。

   那么,我们应该怎么做呢?其实步骤不太难:

    (1)在第n行寻找可以插入的位置,中间涉及到位置合法性的判断

    (2)如果没有可以插入的位置,返回

    (3)如果有可以插入的位置, 插入数据。此时再判断是否已经是最后一行,如果是,打印输出返回;反之继续对下一行数据进行试探处理。

    有了上面的步骤,我们就可以书写代码了。老规矩,朋友们可以自己先尝试一下。

    9159.com 19159.com 2

  1. static int gEightQueen[8] = {0};  
  2. static int gCount = 0;  
  3.   
  4. void print()  
  5. {  
  6.     int outer;  
  7.     int inner;  
  8.   
  9.     for(outer = 0; outer <8; outer  ){  
  10.         for(inner = 0; inner < gEightQueen[outer]; inner  )  
  11.             printf("* ");  
  12.   
  13.         printf("# ");  
  14.   
  15.         for(inner = gEightQueen[outer]   1; inner < 8; inner  )  
  16.             printf("* ");  
  17.   
  18.         printf("n");  
  19.     }  
  20.   
  21.     printf("=====================================n");  
  22. }  

**    9159.com 39159.com 4**

  1. int check_pos_valid(int loop, int value)  
  2. {  
  3.     int index;  
  4.     int data;  
  5.   
  6.     for(index = 0; index < loop; index  ){  
  7.         data = gEightQueen[index];  
  8.   
  9.         if(value == data)  
  10.             return 0;  
  11.   
  12.         if((index   data) == (loop   value))  
  13.             return 0;  
  14.   
  15.         if((index - data) == (loop - value))  
  16.             return 0;  
  17.     }  
  18.   
  19.     return 1;  
  20. }  

**    9159.com 59159.com 6**

  1. void eight_queen(int index)  
  2. {  
  3.     int loop;  
  4.   
  5.     for(loop = 0; loop < 8; loop ){  
  6.         if(check_pos_valid(index, loop)){  
  7.             gEightQueen[index] = loop;  
  8.   
  9.             if(7 == index){  
  10.                 gCount  , print();  
  11.                 gEightQueen[index] = 0;  
  12.                 return;  
  13.             }  
  14.               
  15.             eight_queen(index   1);  
  16.             gEightQueen[index] = 0;  
  17.         }  
  18.     }  
  19. }  

ps:**

 

    下面是完整的代码,大家可以直接保存成queue.cpp,直接编译运行即可。可以打印出所有92种情况,

[cpp] view plaincopy9159.com 79159.com 8

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. static int gEightQueen[8] = {0};  
  5. static int gCount = 0;  
  6.   
  7.   
  8. void print()  
  9. {  
  10.     int outer;  
  11.     int inner;  
  12.   
  13.     for(outer = 0; outer <8; outer  ){  
  14.         for(inner = 0; inner < gEightQueen[outer]; inner  )  
  15.             printf("* ");  
  16.   
  17.         printf("# ");  
  18.   
  19.         for(inner = gEightQueen[outer]   1; inner < 8; inner  )  
  20.             printf("* ");  
  21.   
  22.         printf("n");  
  23.     }  
  24.   
  25.     printf("=====================================n");  
  26. }  
  27.   
  28. int check_pos_valid(int loop, int value)  
  29. {  
  30.     int index;  
  31.     int data;  
  32.   
  33.     for(index = 0; index < loop; index  ){  
  34.         data = gEightQueen[index];  
  35.   
  36.         if(value == data)  
  37.             return 0;  
  38.   
  39.         if((index   data) == (loop   value))  
  40.             return 0;  
  41.   
  42.         if((index - data) == (loop - value))  
  43.             return 0;  
  44.     }  
  45.   
  46.     return 1;  
  47. }  
  48.   
  49.   
  50.   
  51. void eight_queen(int index)  
  52. {  
  53.     int loop;  
  54.   
  55.     for(loop = 0; loop < 8; loop ){  
  56.         if(check_pos_valid(index, loop)){  
  57.             gEightQueen[index] = loop;  
  58.   
  59.             if(7 == index){  
  60.                 gCount  , print();  
  61.                 gEightQueen[index] = 0;  
  62.                 return;  
  63.             }  
  64.               
  65.             eight_queen(index   1);  
  66.             gEightQueen[index] = 0;  
  67.         }  
  68.     }  
  69. }  
  70.   
  71.   
  72.   
  73. int main(int argc, char* argv[])  
  74. {  
  75.     eight_queen(0);  
  76.     printf("total = %dn", gCount);  
  77.     return 1;  

       if(x < 0 || x>= MAX_NUMBER_LENGTH || y < 0 || y >= MAX_NUMBER_LENGTH)

 

 

八皇后是一道很具典型性的题目。它的基本要求是这样的:在一个8*8的矩阵上面放置8个物体,一个矩阵点只允许放置一个物体,任意两个点不能在一行上,也不能在一列上,不能在一条左斜线上,当然也不能在一条右斜线上。

 

    第一次排序:1,2,5,4,9

   

        if(2 == gPath[x][y]){ 

 

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

    c)接着,我们编写一个递归的寻找算法即可

 

 

int check_pos_valid(int x, int y) 

    a)算法步骤

 

       {

       int index;

初看到这道题目,大家的第一印象是遍历,但是经过实践之后发现遍历其实不好写,而且复杂度很低。不仅需要遍历8*8*8*8*8*8*8*8*8

2^24次数据,还要判断各种条件,实际的计算复杂度还要比较这个高。其实我们仔细看一看,这中间很多的计算其实很多是不需要的,因为如果我们在某一行没有可以插入的数据的话,那么这后面的行其实就不用考虑了。也就是说,我们只有在保证前面 插入的物体都合法有效的情况下,才能进行下一次的物体插入。无谓的遍历只会是无用功。

 

   那么,我们应该怎么做呢?其实步骤不太难:

 

    (1)在第n行寻找可以插入的位置,中间涉及到位置合法性的判断

 

    (2)如果没有可以插入的位置,返回

 

    (3)如果有可以插入的位置, 插入数据。此时再判断是否已经是最后一行,如果是,打印输出返回;反之继续对下一行数据进行试探处理。

 

    有了上面的步骤,我们就可以书写代码了。老规矩,朋友们可以自己先尝试一下。

 

    a)定义全局堆栈和打印函数

 

 

static int gEightQueen[8] = {0}; 

static int gCount = 0; 

 

void print() 

    int outer; 

    int inner; 

 

    for(outer = 0; outer <8; outer ){ 

        for(inner = 0; inner < gEightQueen[outer]; inner ) 

            printf("* "); 

 

        printf("# "); 

 

        for(inner = gEightQueen[outer] 1; inner < 8; inner ) 

            printf("* "); 

 

        printf("n"); 

    } 

 

    printf("=====================================n"); 

static int gEightQueen[8] = {0};

static int gCount = 0;

 

void print()

{

       int outer;

       int inner;

 

       for(outer = 0; outer <8; outer ){

              for(inner = 0; inner < gEightQueen[outer]; inner )

                     printf("* ");

 

              printf("# ");

 

              for(inner = gEightQueen[outer] 1; inner < 8; inner )

                     printf("* ");

 

              printf("n");

       }

 

       printf("=====================================n");

}

    b)添加位置合法性的函数判断

 

 

int check_pos_valid(int loop, int value) 

    int index; 

    int data; 

 

    for(index = 0; index < loop; index ){ 

        data = gEightQueen[index]; 

 

        if(value == data) 

            return 0; 

 

        if((index data) == (loop value)) 

            return 0; 

 

        if((index - data) == (loop - value)) 

            return 0; 

    } 

 

    return 1; 

int check_pos_valid(int loop, int value)

{

       int index;

       int data;

 

       for(index = 0; index < loop; index ){

              data = gEightQueen[index];

 

              if(value == data)

                     return 0;

 

              if((index data) == (loop value))

                     return 0;

 

              if((index - data) == (loop - value))

                     return 0;

       }

 

       return 1;

}    c) 八皇后遍历

 

 

void eight_queen(int index) 

    int loop; 

 

    for(loop = 0; loop < 8; loop ){ 

        if(check_pos_valid(index, loop)){ 

            gEightQueen[index] = loop; 

 

            if(7 == index){ 

                gCount , print(); 

                gEightQueen[index] = 0; 

                return; 

            } 

             

            eight_queen(index 1); 

            gEightQueen[index] = 0; 

        } 

    } 

void eight_queen(int index)

{

       int loop;

 

       for(loop = 0; loop < 8; loop ){

              if(check_pos_valid(index, loop)){

                     gEightQueen[index] = loop;

 

                     if(7 == index){

                            gCount , print();

                         gEightQueen[index] = 0;

                            return;

                     }

                    

                     eight_queen(index 1);

                     gEightQueen[index] = 0;

              }

       }

}

总结:

 

    (1)迭代递归是编程的难点,需要自己好好实践,看别人写一百遍,不如自己写一遍

 

    (2)递归的时候务必注意函数return的出口

 

    (3)递归函数中语句的顺序不要随意更换

 

    (4)递归函数中注意数据的保存和恢复

 

    (5)递归函数也要验证,可以用程序验证法,也可以用其他函数的结果来验证

声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 八皇后是一道很具典型性的题目。它的基本要求是这样...

    { 

       print(data, size);

 

{

    第三次排序:1,2,4,5,9

 

}

                index = inner; 

    {0 , 1, 1, 1, 1, 0}, 

        } 

                            value = array[inner];

        return 0; 

   第二次排序:1,2,5,4,9

            gValue[x][y] = '#'; 

    int data[] = {2, 1, 5, 4, 9}; 

 

              find_path(x, y 1);

    (1)每次排序的时候都需要寻找第n小的数据,并且和array[n-1]发生交换

                     return 1;

}

            return 1; 

    for(index = 0; index < length; index ) 

 

       int inner, outer, index, value, median;

}

              }

 

    (2)等到n个数据都排序好,那么选择排序结束。

       /* 当前节点是否存在路*/

    c) 测试用例

#define MAX_NUMBER_LENGTH 6  

    第四次排序:1,2,4,5,9

       return 0;

 

{

         

       }

       for(outer = 0; outer < length - 1; outer )

 

              value = array[outer];

                     return 1;

    b)排序代码

 

        } 

 

 

 

 

 

              array[outer] = median;

                     return 1;

    } 

       int outer;

声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 选择排序是和冒泡排序差不多的一种排序。和冒泡排序...

       }

       }

    d)为了验证我们的算法是否正确,可以编写一个打印函数

 

        gValue[x][y] = '#'; 

    } 

 

       {0 , 0, 1, 1, 1, 0}

   

}

              median = array[index];

    {1,  1, 0, 0, 1, 0}, 

        value = array[outer]; 

       for(outer = 0; outer < MAX_NUMBER_LENGTH; outer ){

 

        if(find_path(x 1, y)) 

 

        array[outer] = median; 

    {0 , 0, 1, 0, 1, 2}, 

        return; 

 

 

              gValue[x][y] = '#';

void print(int array[], int length)

    /* 当前节点是否存在路*/ 

 

 

             

              printf("n");

 

              return 0;

        if(index == outer) 

 

              return;

            continue; 

    /* 节点是否出边界*/ 

    2)算法可以先在草稿纸上验证一遍,然后开始编程

    {0 , 0, 1, 0, 1, 0}, 

}

 

    int size = sizeof(data)/sizeof(int); 

    } 

 

 

                     return ;

                     print_path();

       if(NULL == array || 0 == length)

#define MAX_NUMBER_LENGTH 6

    int inner, outer, index, value, median; 

 

总结:

            gValue[x][y] = '#'; 

                     }

 

        gValue[x][y] = 0; 

            } 

        return 0; 

 

 

 

              if(find_path(x 1, y))

                            index = inner;

    } 

{

       return 1;

              index = outer;

 

void select_sort(int array[], int length) 

        if(2 == gPath[x][y]){ 

{

};

 

              find_path(x, y-1);

    if(NULL == array || 0 == length) 

              gValue[x][y] = 0;

        } 

 

        printf("n"); 

    那么从上面的排序步骤可以看到,选择排序应该是这样的:

        } 

       if(NULL == array || 0 == length)

                     printf("%c ", gValue[outer][inner]);

 

    /* 当前节点是否已经走过*/ 

 

思考题:

 

            return 1; 

 

        median = array[index]; 

       {0 , 0, 0, 0, 1, 1},

 

              return 0;

    2,1,5,4,9

       {0 , 0, 1, 0, 1, 0},

       int size = sizeof(data)/sizeof(int);

        if(find_path(x-1, y)) 

    { 

    return 0; 

 

    if(check_pos_valid(x,y)) 

             

 

void test() 

        array[index] = array[outer]; 

    a)首先,我们用矩阵表示地图:其中1表示路,0表示没有路,2表示终点,起始地点为(1,0)

        return; 

 

       {1,  1, 0, 0, 1, 0},

 

        gValue[x][y] = 0; 

    int index; 

 

 

 

 

       if(check_pos_valid(x,y))

              return;

    寻路是游戏设计中需要使用到一种功能,那么我们怎么样以一个点作为起始点,快速地寻找到目标点呢?其实寻路的方法不难。一种简单有效的方法就是回溯法。如果我们从一个点出发,那么这个点周围肯定有若干条路,只要有一条路存在,我们就一直走下去,直到发现没有路走为止;要是发现路走不下去了怎么办,那就只好回头了,我们只能从剩下的选项中继续选择一条路,继续尝试。如果很不幸,所有的尝试都结束了,还是没有发现目标节点,那只能说明,我们真的无路可走。

              for(inner = outer 1; inner < length; inner ){

    if('#' == gValue[x][y]) 

            if(array[inner] < value){ 

            return 1; 

       int data[] = {2, 1, 5, 4, 9};

 

       select_sort(data, size);

       {0 , 0, 1, 0, 1, 2},

    if(NULL == array || 0 == length) 

static int gValue[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {0}; /* 记录已走过的路*/ 

void print(int array[], int length) 

 

 

              if(2 == gPath[x][y]){

        for(inner = outer 1; inner < length; inner ){ 

              }

}

 

{

       {0 , 1, 1, 1, 1, 0},

 

                     gValue[x][y] = 0;

              if(index == outer)

{

                value = array[inner]; 

 

                     continue;

 

    for(outer = 0; outer < length - 1; outer ) 

 

 

       /* 节点是否出边界*/

              }

         

       if('#' == gValue[x][y])

    select_sort(data, size); 

              if(find_path(x-1, y))

 

              if(find_path(x, y-1))

    print(data, size); 

    {0 , 0, 1, 1, 1, 0} 

void test()

            return 1; 

        index = outer; 

    if(0 == gPath[x][y]) 

              array[index] = array[outer];

 

       for(index = 0; index < length; index )

        return 0; 

 

static int gValue[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {0}; /* 记录已走过的路*/

 

int check_pos_valid(int x, int y)

 

       {

                     if(array[inner] < value){

        gValue[x][y] = '#'; 

       {

}; 

        printf("%d", array[index]); 

 

    1)其实测试的方法很多,打印就是比较不错的方式,不过只适合测试用例比较少的情形

        find_path(x-1, y); 

              printf("%d", array[index]);

       int inner;

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

void find_path(int x, int y)

void select_sort(int array[], int length)

int find_path(int x, int y) 

 

void print_path() 

 

 

              find_path(x 1, y);

              if(find_path(x, y 1))

 

    上面的题目介绍了寻路的方法,介绍了如何遍历所有的可能路径。当然你可以从这所有的寻找路径中寻找出一条最短的路径。但是朋友们可以思考一下,有没有一种方法,可以一下子寻找到最优的路径呢?

    { 

    int inner; 

       if(check_pos_valid(x,y))

static int gPath[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = { 

                     return 1;

void find_path(int x, int y) 

 

    b)其实,我们编写一个判断函数,判断当前节点是否合法

 

              return 0;

int find_path(int x, int y)

 

            return ; 

        return 0; 

    e)上面c中所描述的算法只是寻找一条路,那么如果想遍历所有的道路,算法应该怎么修改呢?

        if(find_path(x, y-1)) 

              gValue[x][y] = '#';

              gValue[x][y] = 0;

 

    for(outer = 0; outer < MAX_NUMBER_LENGTH; outer ){ 

声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 寻路是游戏设计中需要使用到一种功能,那么我们怎么...

    if(check_pos_valid(x,y)) 

 

 

    int outer; 

 

        find_path(x, y-1); 

 

            return 1; 

            printf("%c ", gValue[outer][inner]); 

 

        for(inner = 0; inner < MAX_NUMBER_LENGTH; inner ){ 

 

       /* 当前节点是否已经走过*/

              if(2 == gPath[x][y]){

              return 0;

                     gValue[x][y] = '#';

        find_path(x, y 1); 

        find_path(x 1, y); 

static int gPath[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {

                     gValue[x][y] = '#';

    {0 , 0, 0, 0, 1, 1}, 

 

    return 1; 

       if(0 == gPath[x][y])

    if(x < 0 || x>= MAX_NUMBER_LENGTH || y < 0 || y >= MAX_NUMBER_LENGTH) 

       }

              }

void print_path()

              find_path(x-1, y);

                     return 1;

{

            print_path(); 

            gValue[x][y] = 0; 

 

 

 

              for(inner = 0; inner < MAX_NUMBER_LENGTH; inner ){

 

        if(find_path(x, y 1)) 

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

本文由9159.com发布于编程,转载请注明出处:0表示没有路,当然也不能在一条右斜线上9159.c

关键词: 9159.com