知识点:深搜剪枝,暴力

题意:

给定n个方块左上角和右下角坐标及其目标颜色。用画刷去涂,且每次涂的色块必须位于色块上方的和该色块临接的所有色块都已经被涂上颜色。计算画刷更换颜色的最少次数。

题解思路:

比较简单,但是一开始对于刷色块的次序犯了难,感觉是拓扑排序啥的,实际上根据数据范围,最多16个色块,直接暴力枚举就很轻松了。

题解代码:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<string>
#include<cstring>
#include<algorithm>
#define rep(i,l,n) for(int i=(l);i<=(n);++i)
#define ll long long
using namespace std;
int t,n,ans=0x7f7f7f7f;
struct node
{
    int x1,x2,y1,y2,color;
}e[20];
int vis[20];
bool check(int x)
{
    if(vis[x])return 0;
    rep(i,1,n)
    {
        if(e[i].y2==e[x].y1
        &&((e[i].x1<=e[x].x2&&e[i].x2>=e[x].x2)||(e[i].x2>=e[x].x1&&e[i].x1<=e[x].x1)))
        {
            if(vis[i]==0)return 0;
        }
    }
    return 1;
}
void dfs(int cs,int tepans,int last_color)
{
    if(tepans>ans)return;
    if(cs==n+1)
    {
        ans=tepans;
        return;
    }
    rep(i,1,n)
    {
        if(check(i))
        {
            vis[i]=1;
            if(e[i].color==last_color)
            {
                dfs(cs+1,tepans,last_color);
            }
            else
            {
                dfs(cs+1,tepans+1,e[i].color);
            }
            vis[i]=0;
        }
    }
    return;
}
void solve()
{
    scanf("%d",&n);
    rep(i,1,n)scanf("%d%d%d%d%d",&e[i].y1,&e[i].x1,&e[i].y2,&e[i].x2,&e[i].color);
    dfs(1,0,0);
    printf("%d\n",ans);
}
int main()
{
    solve();
    system("pause");
    return 0;
}
 posted on 2022-09-21 22:35  8号选手  阅读(54)  评论(0)    收藏  举报