zoukankan      html  css  js  c++  java
  • 再次优化过的8皇后问题

    其实我没有做到记忆一些已经判定过的状态,增加trace来记忆已判定状态,去掉重复判断

    #include <stdio.h>
    
    #define N 9 
    int q[N] = {0};
    int not_end = 1;
    int trace = 0;
    int cnt = 0;
    int sum = 0;
    
    void print_q() {
        int i;
    
        for (i=0; i<N; i++) printf("%d ", q[i]);
    
        printf("
    ");
    
        return;
    }
    
    int can_put(int m, int n) {
        int i,j;
    
        sum++;
    
        //row is ok
        //colume
        for (i=0; i<m; i++) {
            if (q[i] == n) return 0;
        }
    
        //left-up
        for (i=m-1,j=n-1; i>=0 && j>=0; i--,j--) {
            if (q[i] == j) return 0;
        }
    
        //right-up
        for (i=m-1,j=n+1; i>=0 && j<N; i--,j++) {
            if (q[i] == j) return 0;
        }
    
        return 1;
    }
    
    void next_qn() {
        while (trace >= 0) {
            if (q[trace] < N-1) {
                q[trace] +=1;
                break;
            }
    
            q[trace] = 0;
            trace--;
        }
    
        if ( trace < 0) {
            not_end = 0;
        } else {
            int i = trace + 1;
            while (i < N) {
                q[i] = 0;
                i++;
            }
        }
    
        return;
    }
    
    int main(int argc, char* argv[]) {
        while (not_end) {
            int i;
    
            for (trace; trace<N; trace++) {
                if (!can_put(trace, q[trace])) break;
            }
    
            if (trace == N) {
                cnt++;
                //print_q();
                trace--;
                next_qn(N-1);
            } else {
                next_qn();
            }
        }
    
        printf("CNT: %d, times: %d
    ", cnt, sum);
    
        return 0;
    }

    再次执行就好看多了

    CNT: 352, times: 72378
    
    real    0m0.007s
    user    0m0.004s
    sys    0m0.000s

    我们可以看到判定次数已经和递归一样,也就是说已经成功的用循环替代了递归,并且执行的时间少了0.001s,这大概是省在来回搬栈上了。

    N = 16,跑了12m,再大,估计我的机器跑不动了。不过这个算法的时间复杂度怎么算呢?

    CNT: 14772512, times: 842815472
    
    real    12m26.208s
    user    12m25.835s
    sys    0m0.028s

    大概这是我的最终答案了,找时间去网上找找经典问题的经典解,或许能学到更有趣的事情。

  • 相关阅读:
    计网第一章——基本概念
    计网第二章——应用层
    命令行测试邮件发送工具mailsend-go
    CentOS-7-x86_64-DVD-2009 rpm包列表(centos7.9)
    CentOS-7-x86_64-Everything-2009 rpm包列表(CentOS7.9)
    Centos发行版ISO镜像中rpm包列表
    nginx使用记录
    centos resolv.conf
    python cookbook
    ansible中变量和主机名
  • 原文地址:https://www.cnblogs.com/sig3/p/3940917.html
Copyright © 2011-2022 走看看