首页 > 其他分享 >涂满它!(涂色问题 (原题:水叮当的舞步))题解

涂满它!(涂色问题 (原题:水叮当的舞步))题解

时间:2023-01-17 20:11:55浏览次数:64  
标签:10 颜色 格子 水叮当 int 题解 nx 涂色 return

F. 涂满它!

内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较

题目描述

Flood-it是谷歌+平台上的非常好玩的一款游戏,游戏界面如下所示:

avatar

在游戏开始时,系统将随机生成N×N的方形区域,并且区域内的每个网格都被涂成了六种颜色中的一种。

玩家从左上角开始游戏。

在每个步骤中,玩家选择一种颜色并将与左上角连通的所有格子(包括左上角)都变成该种颜色。

这里连通定义为:两个格子有公共边,并且颜色相同。

通过这种方式,玩家可以从左上角开始将所有格子都变为同一种颜色。

下图显示了4×4游戏的最早步骤(颜色标记为0到5):

avatar

请你求出,给定最初区域以后,最少要多少步才能把所有格子的颜色变成一样的。


 

输入格式

输入包含不超过20个测试用例。

每个测试用例,第一行包含一个整数N,表示方形区域大小。

接下里N行,每行包含N个整数(0-5),第 i 行第 j 个整数表示第 i 行第 j 列的格子的颜色。

当输入样例N=0时,表示输入终止,该用例无需处理。


 

输出格式

每个测试用例输出一个占据一行的整数,表示所需最少步数。

样例

样例输入

2
0 0 
0 0
3
0 1 2
1 1 2
2 2 1
0

样例输出

0
3


数据范围与提示

2≤N≤8


思路分析

事实证明,我现在还并没有写出题目。。。

但是这并不妨碍我理清思路在写题解。。。

首先我们知道这是一道搜索题,然后还是一道A*,我们并不明确最后是以什么颜色结束的,所以一定不是双向搜索

一共有六种颜色,最多有64个格子。

我们知道,最好的情况就是所有对角线上的颜色都是一样的,这样我们就只需要n - 1的次数就能成功。

我首先尝试寻找剩下的没有填的格子中一共有多少种不同的颜色,然后以这一点来指定规则。

我们用iddfs来解决主要问题,dep的最大值肯定不超过n*n,所以无需担心无穷枚举下去,总是会找到答案的。

 

又仔细思考过后,我们的思路会更加清晰

1.A*

寻找没有走过的格子中有多少个颜色不一样,这就是我们的h

2.Dye染色

我们用Vis数组来标记,0表示这个点没有走到过,1表示这个点已经被同色了,不管后面怎么改动(1,1),它都会被一起更改,2表示我们在某个是1的点可以走到2,这样我们下次染色时,这个点是2且与更换的颜色相同,就可以直接更改了。

3.A_iddfs

常规操作:先预判,如果不满足条件的话就直接return,再写出口。分别枚举5个颜色,对地图进行染色。(我们大多数人可能都懂,但是代码要怎么具体实现呢?)


代码部分

 

#include <bits/stdc++.h>
using namespace std ;
int a[10][10], n, dep = 0, s ;
int Vis[10][10] ;
int rx[5] = {-1, 1, 0, 0} ;
int ry[5] = {0, 0, -1, 1} ;
bool flag = 0 ;
int h()
{
    int sum = 0, cl[7] ;
    memset(cl, 0, sizeof(cl)) ;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            if(Vis[i][j] != 1 && !cl[a[i][j]]){//!这里的Vis[i][j]可以等于2,所以不能只判零 
                sum ++ ;
                cl[a[i][j]] = 1 ;
            } 
        }
    }
    return sum ;
}
bool out(int x, int y){
    if(x <= 0 || x > n || y <= 0 || y > n) return false ;
    return true ;
}
void Dye(int c, int x, int y){
    
    Vis[x][y] = 1 ;
    for(int i = 0; i < 4; i ++)
    {
        int nx = x + rx[i], ny = y + ry[i] ;
        if(out(nx, ny) == false || Vis[nx][ny]) continue ;
        Vis[nx][ny] = 2 ;
        if(a[nx][ny] == c){
            Dye(c, nx, ny) ;
        }
    }
    return ;
} 
void A_iddfs(int tot)
{
    int num = h() ;
    if(tot + num > dep) return ;
    if(num == 0){
        flag = 1 ;
        return ;
    }
    int ori[10][10] ;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            ori[i][j] = Vis[i][j] ;
        }
    } 
    for(int c = 0; c <= 5; c ++){
        bool f = 0 ;
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= n; j ++){
                if(Vis[i][j] == 2 && a[i][j] == c){
                    Dye(c, i, j) ;
                    f = 1 ;//更改了颜色 
                }
            }
        }
        if(f == 1) A_iddfs(tot + 1) ;
        if(flag == 1) return ;
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= n; j ++){
                Vis[i][j] = ori[i][j] ;//相当于回溯,如果不填充这个颜色就还原。 
            }
        }
    }
}
int main()
{
    while(scanf("%d", &n) != EOF && n != 0)
    {
        flag = 0 ;
        dep = 0 ; 
        memset(Vis, 0, sizeof(Vis)) ;
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= n; j ++){
                scanf("%d", &a[i][j]) ; 
            }
        }
        Dye(a[1][1], 1, 1) ;
        while(!flag){
            A_iddfs(0) ;
            dep ++ ;
        }
        printf("%d\n", dep - 1) ;
    }
    return 0 ;
} 

 

————————Hellioca 2023-01-1719:52:48 归零——一切过往,皆为序章。所有未来,皆是可期。

 

标签:10,颜色,格子,水叮当,int,题解,nx,涂色,return
From: https://www.cnblogs.com/ybC202444/p/17058615.html

相关文章

  • 2023牛客寒假算法基础集训营1题解
    写在前面全文收集了部分学长以及我自己的代码,本蒟蒻第一次写博客,效果不好请见谅TwT原题链接:https://ac.nowcoder.com/acm/contest/46800#questionA:WorldFinal?WorldC......
  • 洛谷普及组模拟赛 题解报告
    洛谷普及组模拟赛题解报告\[\bf{Prepared\by\InoueTakina.}\]前言:祝大家身体健康。本场比赛较为良心,经过了多次难度平衡,应该严格低于NOIP2018提高组,相信大家......
  • 洛谷P3195 玩具装箱 题解报告
    题目地址题意:如题所述。分析:斜率优化dp模板题。题目没看清就下手,自以为题面所述中i>j;原始dp式子也没设计准确。中途在错误方向上头铁时,甚至没注意到横坐标是沿......
  • 洛谷P3628 特别行动队 题解报告
    题目地址题意:把正整数序列分隔为若干区间,若单个区间的元素之和为X,则其贡献为\(aX^2+bX+c\)。求所有区间的贡献之和的最大值。分析:斜率优化dp模板题。这篇博客描述得......
  • 1.17模拟赛题解
    T1设\(dp_{i,j}\)前\(i+j\)个人站队,第一排站\(i\)个人的方案数。每次对相同身高的一段人进行转移。暴力复杂度是正确的。时间复杂度\(O(n^2)\)。T4考虑二分答......
  • iSCSI的客户端messages频繁报错问题解决
    问题现象:在自己的工作站中安装的RAC测试环境,使用了iSCSI模拟共享存储,环境运行OK,但是在messages信息中频繁报错如下:[root@db01rac2~]#tail-20f/var/log/messagesJan......
  • 送礼物题解
    题目描述达达帮翰翰给女生送礼物,翰翰一共准备了N个礼物,其中第i个礼物的重量是G[i]。达达的力气很大,他一次可以搬动重量之和不超过W的任意多个物品。达达希望一次搬......
  • 清单计价-2022鹏业云计价i20常见问题解答整理
    1、如何批量将EXCEL报表的工程结构、清单和定额一次性导入计价软件?答:通过云计价i20软件的“导入Excel新建”功能,可以将招标控制价、投标报价等多种类型的表格一次性导入软件......
  • CF1748B题解
    题目传送门简要题意给定一个长度为\(n\)的只由数字\(0\)到\(9\)组成的字符串\(s\),求\(s\)中有多少个子串满足所有数字出现次数的最大值小于等于出现的不同数......
  • THUCTF MISC题解
    永不停歇的Flag生产机这是一台永不停歇的Flag生产机,它会生产出许许多多的Flag供你挑选和使用,就连这道题的Flag也是由这台生产机制造出来的。哦放心,我知道你想......