• n皇后问题


    递归算法

    bool valid(vector<int> &res, int r)
        {  
            int nCol = res.size();
            for(int i=0;i<nCol;i++){  
                if(res[i]==r || abs(res[i]-r)==nCol-i){  
                    return false;  
                }  
            }
            return true;  
        } 
    
        void queen(int n, int l, vector<int> res, int &nCount)
        {
            if (l == n)
            {
                nCount++;
                return;
            }
            for (int i=0; i<n; i++)
            {
                if (!valid(res, i))
                    continue;
        
                res.push_back(i);
                queen(n, l+1, res, nCount);
                res.pop_back();
            }
        }
        int totalNQueens(int n) {
            vector<int> vec;
            int nCount = 0;
            queen(n, 0, vec, nCount);
            return nCount;
        }

    非递归算法:

    int place(vector<int> &x, int k)
    {
      int j;
      
      for (j = 0; j < k; j++)
      {
        if ((abs(k - j) == abs(x[j] - x[k])) || (x[j] == x[k]))
          return 0;
      }
      return 1;
    }
    
    int totalNQueens1(int n) {
        vector<int> x(n);
        int nCount = 0;
        
        for (int i = 0; i < n; i ++)
        {
            x[i] = 0;
        }
    
        x[0] = -1;
        int k = 0;
        while (k >= 0)
        {
            x[k] += 1;
            while ((x[k] < n) && !(place(x, k)))
                x[k] += 1;
            if (x[k] < n)
            {
                if (k == n - 1)
                    nCount++;
                else
                {
                    k++;
                    x[k] = -1;
                }
            }
            else
                k--;
        }
    
        return nCount;
    }

    最高效的算法

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    long sum = 0, upperlim = 1;
    
    void test(long row, long ld, long rd) \row表示已经有皇后的行,ld、rd分别表示已经有皇后的斜列,每一位表示该列中可以摆放皇后的位置,1表示可以摆放,0表示不可以摆放。row在每查找下一列时不用改动,ld、rd需要分别左移和右移一位。
    {
    
       if (row != upperlim) \当所有行都有皇后时说明摆放完毕
       {
      long pos = upperlim & ~(row | ld | rd); \pos的每一位表示该列中可以摆放皇后的位置,1表示可以摆放,0表示不可以摆放
      while (pos) \如果pos中还有可以摆放的位置
      {
     long p = pos & -pos; \p为pos中最末一个可以摆放的位置
    
     pos -= p; \将p从可摆放位置去掉
     test(row + p, (ld + p) << 1, (rd + p) >> 1); \对下一列进行判断
      }
       } else
      sum++;
    }
    
    int main(int argc, char *argv[])
    {
       time_t tm;
       int n = 16;
    
       if (argc != 1)
      n = atoi(argv[1]);
       tm = time(0);
       if ((n < 1) || (n > 32))
       {
      printf(" 只能计算1-32之间
    ");
      exit(-1);
       }
       printf("%d 皇后
    ", n);
       upperlim = (upperlim << n) - 1;
    
       test(0, 0, 0);
       printf("共有%ld种排列, 计算时间%d秒 
    ", sum, (int) (time(0) - tm));
    }
  • 相关阅读:
    Java 分支结构
    Java 循环结构
    Java 运算符
    Java 修饰符
    Alpha冲刺——Day 6
    Alpha冲刺——Day 5
    Alpha冲刺——Day 4
    Alpha冲刺——Day 3
    Alpha冲刺——Day 2
    Alpha冲刺——Day 1
  • 原文地址:https://www.cnblogs.com/zhhwgis/p/3959894.html
Copyright © 2020-2023  润新知