SZUOJ-大作业

来源:互联网 发布:学淘宝基础知识 编辑:程序博客网 时间:2024/06/05 04:28


世界名画陈列馆由 mx n个陈列室组成为防止名画被盗,需要在陈列室中设置警卫机器人哨位每个警卫机器人除了监视它所在的陈列室外,还可监视与它所在陈列室相邻的上、下、左、右 4个陈列室设计一个算法,安排警卫机器人哨位,使得名画陈列馆中每一个陈列室都在警卫机器人的监视之下,且所用的警卫机器人最少:

#include <iostream>#include <string.h>#include <cmath>#include <windows.h>#include <stdlib.h>using namespace std;int n,m,now;bool map[25][25],ans[25][25];inline bool covered(int x,int y)//判断棋子是否被填充或者已经越界 {    if (map[x][y]==true || (x-1>=1 && map[x-1][y]==true) || (x+1<=n && map[x+1][y]==true) || (y-1>=1 && map[x][y-1]==true) || (y+1<=m && map[x][y+1]==true))        return(true);    return(false);}//x,y为坐标,sum为放的格子总数,pre代表上一次放棋子的时候假设空白格子为(x,y),那么pre1==true的时候//棋子中心放在了(x,y)上,pre2为true的时候放在了(x,y+1)上,pre3为true的时候放在了(x+1,y)上 void find(int x,int y,int sum,bool pre1,bool pre2,bool pre3){//表示如果剩下的课放置的次数都填充了最大的5个还小于剩下的棋盘格子总数的时候,肯定不可以;     if (sum>now || (now-sum)*5<(n-x-1)*m) return;    //已经到了最后一个格子     if (x==n && y==m)    {        if (covered(x,y)==false)            sum++;        //如果比上界要小,就保存结果并缩小上界 if (now-sum>=0){for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)ans[i][j]=map[i][j];if (covered(x,y)==false) ans[x][y]=true;now=sum-1;}        return;    }    //如果要换行或者已经被填充为黑色的时候     if (y>m || covered(x,y)==true)    {    //换行的时候把pre都置位f,不换行就保存pre继续dfs;         if (y+1<=m) find(x,y+1,sum,pre1,pre2,pre3);        else find(x+1,1,sum,false,false,false);        return;    }    //三个预判格子都为白色 if (y+1<=m && x+1<=n && covered(x+1,y)==false && covered(x,y+1)==false){//棋子中心放在(x,y) if (pre1==false){map[x][y]=true;find(x,y+1,sum+1,true,false,false);map[x][y]=false;}if (sum>now || (now-sum)*5<(n-x-1)*m) return;//棋子中心放在(x+1,y) if (pre2==false){map[x+1][y]=true;find(x,y+1,sum+1,false,true,false);map[x+1][y]=false;}if (sum>now || (now-sum)*5<(n-x-1)*m) return;//棋子中心放在(x,y+1) if (pre3==false){map[x][y+1]=true;find(x,y+1,sum+1,false,false,true);map[x][y+1]=false;}}//(x,y+1)为黑的时候要中心放在(x+1,y)为最优的 else if (y+1<=m && x+1<=n && covered(x+1,y)==false && covered(x,y+1)==true){map[x+1][y]=true;find(x,y+1,sum+1,false,true,false);map[x+1][y]=false;}//(x+1,y)为黑的时候要中心放在(x,y+1)为最优的  else if (y+1<=m && x+1<=n && covered(x+1,y)==true && covered(x,y+1)==false){map[x][y+1]=true;find(x,y+1,sum+1,false,false,true);map[x][y+1]=false;} //特判(n,m-1) else if (y+1<=m && x+1>n){map[x][y+1]=true;find(x,y+1,sum+1,true,true,false);map[x][y+1]=false;}//特判(n-1,m) else if (y+1>m){map[x+1][y]=true;find(x,y+1,sum+1,false,false,false);map[x+1][y]=false;}}void display()//画出棋盘 {int i,j,k;    cout<<"┏";    for (i=1;i<m;i++) cout<<"━┯";    cout<<"━┓"<<endl;    for (i=0;i<n;i++)    {        if (i)        {            cout<<"┠";            for( k=1;k<m;k++) cout<<"─┼";            cout<<"─┨"<<endl;        }        cout<<"┃";        for(j=0;j<m;j++)        {            if(j) cout<<"│";            if(ans[i+1][j+1]) cout<<"●";            else cout<<"  ";        }        cout<<"┃"<<endl;    }    cout<<"┗";    for(i=1;i<m;i++)        cout<<"━┷";    cout<<"━┛"<<endl;}int main(){    cin>>n>>m;    int s=GetTickCount();    now=ceil((n*m)/3.0);    find(1,1,0,false,false,false);    now++;    cout<<now<<endl;display();int e=GetTickCount();cout<<(e-s)/1000.0<<endl;//计时     return(0);}

0 0
原创粉丝点击