• 1342-皇后控制问题


    描述

     

    在一个nxn个方格组成的棋盘上的任一方格中放置一个皇后,该皇后可以控制他所在 的行,列以及对角线上的所有方格。对于给定的自然数n,在nxn个方格组成的棋盘上最少要放置多少个皇后才能控制棋盘上的所有方格,且放置的皇后互不攻击?

    设计一个拉斯维加斯算法,对于给定的自然数n (1£ n £100)计算在

    nxn个方格组成的棋盘上最少要放置多少个皇后才能控制棋盘上的所有方格,且放置的皇后互不攻击。

    输入

     

    输入的第一行有1个正整数n。

    输出

     

    输出计算出最少皇后数及最佳放置方案,第一行是最少皇后数;接下来的1行是皇后的最佳放置方案。

    样例输入

    8

    样例输出

    5

    0 3 6 0 0 2 5 8

    #include <iostream>
    //#include <fstream.h>
    #include <time.h>
    #include <math.h> 
    #include <stdlib.h>  
    using namespace std;
    //ifstream infile("input.txt"); 
    //ofstream outfile("output.txt");  
    const unsigned long maxshort=65536L;  
    const unsigned long multiplier=1194211693L; 
    const unsigned long adder=12345L; 
    class RandomNumber 
    { 
    public: 
        RandomNumber(void){};
        unsigned long randSeed; 
        RandomNumber(unsigned long s) 
        { 
            if(s==0) 
                randSeed=time(0); 
            else 
                randSeed=s;   
        } 
        unsigned long Random(unsigned long n) 
        { 
            randSeed=multiplier*randSeed+adder; 
            return (unsigned short)((randSeed>>16)%n); 
        }  
        double fRandom(void) 
        { 
            return Random(maxshort)/double(maxshort); 
        } 
    };
    template <class T>  
    void Make2DArray(T** &x, int rows, int cols) 
    { 
        x = new T* [rows]; 
        for(int j = 0; j < rows; j++) 
        { 
            x[j] = new T[cols]; 
        } 
    }  
    template <class T>  
    void Delete2DArray(T** &x, int rows) 
    {  
        for(int j = 0; j < rows; j++) 
        { 
            delete[] x[j]; 
        }     
        delete[] x; 
        x = NULL; 
    } 
    class queen
    {
        friend bool nqueen(int m);
        
        private:
            queen(void){};
            bool place(int k);
            bool backtrack(int t);
            int queenslv(int stopVegas);
            bool ctrl(int m);    
            int n,*x,*y,*a,**z;//n=?????????x=k???????????????x[k]??????y=???????????????????????????
                               //a=????????????????????????z=??????????????????
            int cmin,c;//cmin=?????????????????????c=????????????
            RandomNumber rnd; 
    };
    bool queen::place(int k)
    {
        if(x[k]>0) 
            for(int j=1;j<k;j++) 
                if((x[j]>0)&&((abs(k-j)==abs(x[j]-x[k]))||x[j]==x[k])) 
                    return false; 
            return true; ;
    }
    bool queen::ctrl(int m)
    {
        int i,j,u,v,count=0;
        for(i=1;i<=m;i++)
            for(j=1;j<=m;j++)
                z[i][j]=0;
        for(i=1;i<=m;i++)
        {
            if(x[i]>0)
            {
                for(j=1;j<=m;j++) {z[i][j]=1;z[j][x[i]]=1;}
                for(u=i,v=x[i];u>=1&&v>=1;u--,v--) z[u][v]=1;
                for(u=i,v=x[i];u<=m&&v>=1;u++,v--) z[u][v]=1;
                for(u=i,v=x[i];u>=1&&v<=m;u--,v++) z[u][v]=1;
                for(u=i,v=x[i];u<=m&&v<=m;u++,v++) z[u][v]=1;
            }
        }
        for(i=1;i<=m;i++)
            for(j=1;j<=m;j++)
                count+=z[i][j];//?????????????????????
        return (count==m*m);
    }
    int queen::queenslv(int stopVegas) //????????????n?????????
    {
        int k=1;
        int count;
        c=0;
        while(k<=stopVegas)
        {
            count=0;
            y[count++]=0;
            for(int i=1;i<=n;i++)
            {
                x[k]=i;
                if(place(k)) y[count++]=i;
            }
            if((x[k++]=y[rnd.Random(count)])>0) c++; 
        }
        return c;
    }
    bool queen::backtrack(int t)
    {
        if(t>n)
        {
            if(ctrl(n)&&(c<=cmin))
            {
                a[0]=c;
                for(int i=1;i<=n;i++)
                    a[i]=x[i];
                return true;
            }
            else return false;
        }
        else
        {
            for(int i=0;i<=n;i++)
            {
                x[t]=i;
                if(i>0) c++;
                if((c<=cmin)&&place(t)&&backtrack(t+1))
                    return true;
                if(i>0) c--;
            }
            return false;
        }
    }
    bool nqueen(int n)
    {
        queen X;
        X.n=n;
        int *p=new int [n+1];
        int *q=new int [n+1];
        int *ans=new int [n+1];
        int **r;
        Make2DArray(r,n+1,n+1);        
        for(int i=0;i<n;i++) p[i]=0;    
        X.x=p;
        X.y=q;
        X.z=r;
        X.a=ans;
        X.cmin=n;    
        int stop=3;
        int num=0,stopnum=100;
        if(stop>15) stop=n-15;
        //if(stop>12) stopnum=2;
        while(true)
        {
            while(X.queenslv(stop)==0);
            if(X.backtrack(stop+1))
            {
                num++;
                if(X.c<X.cmin)//??????
                {
                    X.cmin=X.c;
                    num=0;
                }
            }
            if(num>stopnum)
            {
                cout<<ans[0]<<endl;
                for(int i=1;i<n;i++)
                    cout<<ans[i]<<" ";
                cout<<ans[n]<<endl;
                return true;
            }
        }
        delete []p;
        delete []q;
        delete []ans;
        Delete2DArray(r,n+1);
        return true;
    }
    int main()
    {
        int n;
        cin>>n;
        return nqueen(n);
        return 0;
    }
    

      

  • 相关阅读:
    RadGrid Expand/Collapse on Row click
    AutoComplete Textbox with Additional Parameters From Database
    Combobox.Items中添加项Items
    JavaScript 处理字符串(操作字符串)
    用nettiers + svn + resharper + rad + ccNet开发前的准备工作
    Document.location.href和.replace的区别
    .net remoting的事务传播以及wcf分布式事务
    IDA反汇编/反编译静态分析iOS模拟器程序(三)函数表示与搜索函数
    [置顶] 一道有趣的逻辑题
    mini2440uboot移植基本操作指令
  • 原文地址:https://www.cnblogs.com/Rosanna/p/3437049.html
Copyright © 2020-2023  润新知