zoukankan      html  css  js  c++  java
  • [暑假集训Day3T3]平板涂色

    同样是搜索经典题。

    优化并不多,只需在当前步数已经大于目前答案时剪枝就可以了。

    此题重点在于如何判断第k个矩形能不能选。

    设矩形i的左上坐标为i(squ[i].upx,squ[i].upy),右下角坐标为i(squ[i].dox,squ[i].doy)。则判断k号矩形可以涂的条件为:

    if(!vis[i]&&(squ[k].upy==squ[i].doy)&&((squ[i].upx>=squ[k].upx&&squ[i].upx<=squ[k].dox)||(squ[i].dox>=squ[k].upx&&squ[i].dox<=squ[k].dox)))

    即:如果i号矩形没有涂色且i号矩形为紧靠k上方的矩形,就不可以涂色。

    重点来解释一下如何判定i号矩形为紧靠k矩形上方的矩形。

    第一,如果i号矩形为紧靠k矩形上方的矩形,那么i号矩形右下角的纵坐标一定等于k号矩形左上角的纵坐标,这个很好理解,对应判断条件中的(squ[k].upy==squ[i].doy)。

    第二,如何判断[squ[i].upx,squ[i].dox]和[squ[k].upx,squ[i].dox]有没有交集呢?只需要看是否有一个端点位于线段中即可,读者可以结合下图理解:

    下面正常深搜即可。

    下面给出参考代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #define N 205
     4 using namespace std;
     5 struct node
     6 {
     7     int upx,upy,dox,doy,col;
     8 }squ[N];
     9 int n,ans;
    10 bool vis[N];
    11 bool check(int k)
    12 {
    13     for(int i=1;i<=n;i++)
    14     {
    15         if(!vis[i]&&(squ[k].upy==squ[i].doy)&&((squ[i].upx>=squ[k].upx&&squ[i].upx<=squ[k].dox)||(squ[i].dox>=squ[k].upx&&squ[i].dox<=squ[k].dox)))return 0;
    16     }
    17     return 1;
    18 }
    19 void dfs(int step,int node,int col)
    20 {
    21     if(step>=ans)return;
    22     if(node==n)ans=step;
    23     for(int i=1;i<=n;i++)
    24     {
    25         if(!vis[i]&&check(i))
    26         {
    27             if(squ[i].col==col)
    28             {
    29                 vis[i]=1;
    30                 dfs(step,node+1,col);
    31                 vis[i]=0;
    32             }
    33             else 
    34             {
    35                 vis[i]=1;
    36                 dfs(step+1,node+1,squ[i].col);
    37                 vis[i]=0;
    38             }
    39         }
    40     }
    41 }
    42 int main()
    43 {
    44     cin>>n;
    45     ans=n;
    46     for(int i=1;i<=n;i++)
    47     {
    48         cin>>squ[i].upy>>squ[i].upx>>squ[i].doy>>squ[i].dox>>squ[i].col;
    49     }
    50     dfs(0,0,-1);
    51     cout<<ans<<endl;
    52 }
    View Code
  • 相关阅读:
    Visual Studio 2013各个版本密钥(亲测可用)
    Duilib bkimage 属性
    VC++ 文件夹的打开
    孙鑫- VC++在对话框程序中让对话框捕获WM_KEYDOWN消息
    OpenCV窗口置顶的方法
    OpenCV设置感兴趣区域(roi)
    Ubuntu 12,04安装ROS Hydro
    VC获取任务栏窗口及其子窗口句柄
    关于调用静态链接库LIB,提示重定义或库冲突的错误
    DuiLib如何禁用双击标题栏窗口最大化
  • 原文地址:https://www.cnblogs.com/szmssf/p/11173000.html
Copyright © 2011-2022 走看看