Part 1 Basic Algorithms (Enhancement) --Chapter 3 Deep search pruning techniques 1445: Flat painting

Posted by JehovahsWord on Tue, 16 Jun 2020 04:03:38 +0200

1445: Flat Painting

Time limit: 1000 ms memory limit: 65536 KB
Number of submissions: 565 passes: 296
[Title Description]
CE Digital has developed a product called Automatic Color Machine (APM).It can use predefined colors to color a flat panel of rectangles of different sizes that do not cover each other.

For coloring, the APM uses a set of brushes.Each brush is painted with a different color C.APM picks up a brush with colour C and colours all rectangles with colour C that meet the following restrictions:

To avoid a color leak that mixes colors, a rectangle can only be colored after all rectangles immediately above it have been colored.For example, rectangle F in the diagram must be colored C and D before it can be colored.Note that each rectangle must be immediately coated, not just a portion.

Write a program to find a color scheme that minimizes the number of brushes that the APM picks up.Note that if a brush is picked up more than once, it must be counted in the total each time.

[Input]
Number N of first row rectangles.N lines below describe N rectangles.Each rectangle has five integer descriptions, the y and x coordinates in the upper left corner, the y and x coordinates in the lower right corner, and the preset color.

The color number is an integer from 1 to 20.

The upper left corner coordinates of the flat plate are always (0, 0).

The coordinate range is 0...99.N is less than 16.

[Output]
Minimum number of times to pick up the brush.

[Input Sample]
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
[Output Sample]
3

Idea: Optimize the read-in data, count the colors, and try each color once, that is, paint the colored and paintable bricks.Next painting cannot be applied with the last one.Finished recording results.
In order not to time out, two pruning prunes were added: Optimal pruning: Exit directly when the current number of colors is greater than or equal to the current answer.
Feasible pruning: If none of the bricks are currently painted, exit directly, and if you search again, there will be an additional number of times, and there may be an endless cycle.
As to whether the brick can be painted, pretreat it, record the bricks immediately above it in an array, and then judge if they have been painted.

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()//Optimize read-in data
{
   int s=0,f=1;
   char ch=getchar();
   while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
   while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
   return s*f;
}
struct node  //Structure a1, b1 Brick upper left coordinate, a2, b2 lower right coordinate, x color
{
    int a1,b1,a2,b2,x;
}a[20];
int cmp(node a,node b)
{
    if(a.a1!=b.a1) return a.a1<b.a1;
    return a.b1<b.b1;
}
bool d=false;
int de[20];//The de array indicates whether or not the color is present
int n,m,ans=999,b[20],fk[20][20]; //b Array represents whether the brick has been painted
bool OK(int o)
{
    for(int i=1;i<=n;i++)
        if(fk[o][i]&&!b[i]) return false; //If i brick is next to o but i has not been painted, return false
    return true;
}
void dfs(int o,int pq,int xx)//o Number of colors pq colored bricks xx last colored
{
    if(o>=ans) return;//Exit directly if the current number of colors is greater than or equal to the current answer
    if(pq==n)//Finished, record answers
    {
        ans=o;
        return;
    }
    for(int i=1;i<=m;i++)//Enumerated colors
    {
        int oj=0;//Represents the number of bricks now painted in this color
        if(i!=xx&&de[i])//If there's this color, and it's not used last time
        {
            for(int j=1;j<=n;j++) //Painting
                if(!b[j]&&a[j].x==i&&OK(j))
				//If the brick has not been painted and can be painted
                    b[j]=1,oj++;
                else
				if(b[j]&&a[j].x==i)
				b[j]++;
           if(oj>0)
		   dfs(o+1,pq+oj,i);//If brick is applied, proceed to the next step
           for(int j=n;j>=1;j--)//To flash back
                if(b[j]==1&&a[j].x==i&&OK(j))
                    b[j]=0,oj--;
                else
				if(b[j]>1&&a[j].x==i)
				b[j]--; 
        }
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
        a[i].a1=read(),a[i].b1=read(),a[i].a2=read(),a[i].b2=read(),a[i].x=read(),
        a[i].a1++,a[i].b1++,de[a[i].x]++;//Record color
    for(int i=1;i<=20;i++)
	if(de[i])
	m=i; //Find Maximum Color Number
    sort(a+1,a+n+1,cmp);//Sort from smallest to largest by upper left coordinate size (vertical first, then horizontal)
    for(int i=2;i<=n;i++)
        for(int j=i-1;j>=1;j--)//fk[i][j] denotes whether the first brick is adjacent to the jth brick above
            if(a[i].a1==a[j].a2+1&&((a[i].b1>=a[j].b1&&a[i].b1<=a[j].b2)||(a[i].b2>=a[j].b1&&a[i].b2<=a[j].b2)))
                fk[i][j]=1;//If the top of the i-brick is next to the bottom of the j-brick and the horizontal coordinates of the two bricks overlap, that is, the j-brick is the i-brick next to the top of the brick
    dfs(0,0,0);
    printf("%d",ans);//Answer
    return 0;
}

Topics: less