POJ1691-Painting A Board

爷,独闯天下 提交于 2020-03-15 13:16:03

载请注明出处:優YoU  http://blog.csdn.net/lyy289065406/article/details/6727035

 

大致题意:

墙上有一面黑板,现划分为多个矩形,每个矩形都要涂上一种预设颜色C。

由于涂色时,颜料会向下流,为了避免处于下方的矩形的颜色与上方流下来的颜料发生混合,要求在对矩形i着色时,处于矩形i上方直接相邻位置的全部矩形都必须已填涂颜色。

在填涂颜色a时,若预设颜色为a的矩形均已着色,或暂时不符合着色要求,则更换新刷子,填涂颜色b。

 

注意:

1、  当对矩形i涂色后,发现矩形i下方的矩形j的预设颜色与矩形i一致,且矩形j上方的全部矩形均已涂色,那么j符合填涂条件,可以用 填涂i的刷子对j填涂,而不必更换新刷子。

2、  若颜色a在之前填涂过,后来填涂了颜色b,现在要重新填涂颜色a,还是要启用新刷子,不能使用之前用于填涂颜色a的刷子。

3、  若颜色a在刚才填涂过,现在要继续填涂颜色a,则无需更换新刷子。

4、  矩形着色不能只着色一部分,当确认对矩形i着色后,矩形i的整个区域将被着色。

 

首先要注意输入数据,每个矩形信息的输入顺序是 y x y x c,而不是 x y x y c

若弄反了x y坐标怎样也不会AC的.....

 

拓扑思想+DFS

 

       方法还是很直观的,把每个矩形看作一个点,处于黑板最上方的矩形i入度为0,然后从矩形i出发,与其下方直接相邻的矩形连线,这些矩形的入度+1。换而言之,矩形a上方直接相邻的矩形数upNum,就是矩形a(点a)的入度数upNum。

       当矩形i被涂色后,矩形i下方直接相邻的所有矩形的入度数-1。

       那么若一个矩形的入度数为0时,它就是待涂色状态;入度不为0则不允许涂色。

       然后就是按照题目要求的涂色限制条件,DFS涂色方案了,数据量较少,无需剪枝也能AC。

 

最后说说怎样判定矩形a在矩形b的上方。

矩形a与矩形b的基本位置关系共有3种,如下图:

设矩形左上角的坐标为(Lx,Ly) 右下角的坐标为(Rx,Ry)

则先判断Rect[a].Ry==Rect[b].Ly,确定矩形a的底部和矩形b的顶部是否可能重合(直接相邻)

然后再判断3种情况:

情况1:

Rect[a].Lx>=Rect[b].Lx  &&  Rect[a].Lx<Rect[b].Rx

情况2:

Rect[a].Lx<=Rect[b].Lx  &&  Rect[a].Rx>=Rect[b].Rx

情况3:

Rect[a].Rx>Rect[b].Lx  &&  Rect[a].Rx<=Rect[b].Rx

 

注意必须左右方向都要限制,其他特殊情况已由这3种关系所囊括。

 

Source修正:

Tehran 1999

http://code.google.com/p/djudge-core/downloads/detail?name=Tehran-1999.7z&can=2&q=

 

 

  1 //Memory Time      2 //260K  0MS      3     4 #include<iostream>     5 using namespace std;    6     7 struct rectangle    8 {    9     int Lx,Ly;       //左上角坐标     10     int Rx,Ry;       //右下角坐标    11     int SetColor;    //预设着色    12     bool flag;       //标记当前矩形是否已着色    13     int UpNum;       //该矩形上方的矩形数  (UpNum=0表示该矩形上方的矩形已全部被着色,该矩形为待着色状态)    14     int low[16];     //指向该矩形下方的矩形    15     int pl;          //low[]指针    16 };   17    18 class info   19 {   20 public:   21     info(int n=0):N(n)   22     {   23         memset(color,false,sizeof(color));   24         Rect=new rectangle[N+1];   25         initial();   26    27         MinBrushNum=20;   //最多只有15个矩形    28         DFS(0,0,1);   //c==0表示当下对填涂的颜色暂无要求    29     }   30     ~info()   31     {   32         cout<<MinBrushNum<<endl;   33         delete[] Rect;   34     }   35     void initial(void);   36     bool Judge_Upper(int a,int b);  //判断矩形a是否在矩形b上方    37     void DFS(int n,int c,int b);   //n:当前已着色的矩形数,c:当前着色, b:当前正在用第b把刷子    38    39 protected:   40     int N;            //矩形数量    41     rectangle* Rect;  //N个矩形的信息    42     bool color[21];   //标记出现过的颜色    43     int MinBrushNum;  //最少刷子数    44 };   45    46 void info::initial(void)   47 {   48     for(int k=1;k<=N;k++)   49     {   50         cin>>Rect[k].Ly>>Rect[k].Lx;   51         cin>>Rect[k].Ry>>Rect[k].Rx;   52         cin>>Rect[k].SetColor;   53    54         Rect[k].flag=false;   55         Rect[k].UpNum=0;   56         Rect[k].pl=0;   57    58         color[ Rect[k].SetColor ]=true;   59     }   60     for(int i=1;i<N;i++)   61         for(int j=i+1;j<=N;j++)   62         {   63             if(!Judge_Upper(i,j))  //若矩形i不在矩形j上方    64                 Judge_Upper(j,i);  //则判断矩形j是否在矩形i上方    65         }   66     return;   67 }   68    69 bool info::Judge_Upper(int a,int b)   70 {   71     if(Rect[a].Ry==Rect[b].Ly)   72     {   73         if((Rect[a].Lx>=Rect[b].Lx && Rect[a].Lx<Rect[b].Rx) ||    //情况1    74            (Rect[a].Lx<=Rect[b].Lx && Rect[a].Rx>=Rect[b].Rx) ||   //情况2    75            (Rect[a].Rx>Rect[b].Lx && Rect[a].Rx<=Rect[b].Rx))    //情况3    76         {   77             Rect[b].UpNum++;   78             Rect[a].low[ Rect[a].pl++ ]=b;   79             return true;   80         }   81     }   82     return false;   83 }   84    85 void info::DFS(int n,int c,int b)   86 {   87     if(n==N)   88     {   89         if(MinBrushNum > b)   90             MinBrushNum = b;   91         return;   92     }   93    94     if(c==0)  //填涂颜色为随意时,枚举上方矩形均已被涂色的未涂色矩形    95     {   96         for(int i=1;i<=N;i++)   97         {   98             if(!Rect[i].flag && Rect[i].UpNum==0)   99             {  100                 int j;  101   102                 Rect[i].flag=true;  103                 for(j=0;j<Rect[i].pl;j++)   //第i个矩形下方的矩形的UpNum均-1   104                     Rect[ Rect[i].low[j] ].UpNum--;  105   106                 DFS(n+1,Rect[i].SetColor,b);  //下一次填涂的颜色与当次一样,则用同一把刷子   107   108                 Rect[i].flag=false;  109                 for(j=0;j<Rect[i].pl;j++)  110                     Rect[ Rect[i].low[j] ].UpNum++;  111             }  112         }  113     }  114     else  //填涂颜色为上次填涂的颜色   115     {  116         bool tag=false;  117         for(int i=1;i<=N;i++)  118         {  119             if(Rect[i].SetColor==c && !Rect[i].flag && Rect[i].UpNum==0)  120             {  121                 int j;  122                 tag=true;  123   124                 Rect[i].flag=true;  125                 for(j=0;j<Rect[i].pl;j++)   //第i个矩形下方的矩形的UpNum均-1   126                     Rect[ Rect[i].low[j] ].UpNum--;  127   128                 DFS(n+1,c,b);  //下一次填涂的颜色与当次一样,则用同一把刷子   129   130                 Rect[i].flag=false;  131                 for(j=0;j<Rect[i].pl;j++)  132                     Rect[ Rect[i].low[j] ].UpNum++;  133             }  134         }  135   136         if(!tag)  137             DFS(n,0,b+1);  //颜色为c的矩形均已补满足填涂条件,启用新刷子填涂其他颜色   138     }  139     return;  140 }  141   142 int main(void)  143 {  144     int Case;  145     cin>>Case;  146     for(int c=1;c<=Case;c++)  147     {  148         int N;  149         cin>>N;  150         info POJ1691(N);  151     }  152     return 0;  153 }  

 

Sample Input

8

7

0 0 2 2 1

0 2 1 6 2

2 0 4 2 1

1 2 4 4 2

1 4 3 6 1

4 0 6 4 1

3 4 6 6 2

14

0 0 3 2 3

0 2 2 4 1

0 4 1 8 4

1 4 2 7 2

1 7 3 8 1

2 2 3 7 4

3 4 7 6 3

3 6 7 8 4

5 0 8 3 3

5 3 6 4 2

8 0 9 3 2

6 3 9 4 1

7 4 9 8 2

3 0 5 4 4

4

0 0 3 1 1

0 1 2 5 2

0 5 3 6 1

2 1 3 5 1

13

0 0 3 3 1

0 3 2 4 2

0 4 2 5 1

2 3 5 4 1

2 4 3 5 3

3 4 6 5 2

3 2 4 3 1

3 0 4 2 2

4 0 8 1 3

4 1 5 3 2

5 1 6 4 3

6 1 8 3 1

6 3 8 5 1

13

0 0 3 3 1

0 3 2 4 2

0 4 2 5 1

2 3 5 4 1

2 4 3 5 2

3 4 6 5 2

3 2 4 3 1

3 0 4 2 2

4 0 8 1 3

4 1 5 3 2

5 1 6 4 3

6 1 8 3 1

6 3 8 5 1

6

0 0 2 3 9

2 0 3 3 1

3 0 4 3 9

4 0 5 3 1

5 0 6 3 9

6 0 7 3 1

8

0 0 2 3 9

0 3 2 5 1

2 0 3 2 1

2 2 3 4 1

2 4 3 5 2

3 0 4 3 1

3 3 4 5 2

4 0 5 5 3

12

0 0 8 3 9

0 3 2 9 1

2 3 4 5 1

2 5 4 8 1

2 8 4 9 1

4 3 6 4 2

4 4 6 7 2

4 7 5 9 1

5 7 7 9 1

6 3 8 5 1

6 5 8 7 1

7 7 8 9 1

Sample Output

3

8

2

6

5

6

4

4

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!