HDU 5319 Painter (2015 Multi-University Training Contest 3 2015多校联合)

本文解析了一个关于绘画算法的竞赛题目,介绍了如何通过递归的方法计算最少的画笔次数以达到目标图案状态。针对不同颜色的绘制方向进行了详细阐述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2015 Multi-University Training Contest 3  杭电2015多校联合的题~题意是一个人要画画,要从白纸画成输入的样子。R是红色、B是蓝色、G是绿色。G是由红色和蓝色组成的。然后红色只能\这样画,蓝色只能/这样画。(不要想太多,就是斜率为1或-1)'.'是没画的。问你画成输入的图,需要画几笔。这里有个坑,输入的是行数,并不包括列数。列是根据输入的图画而定的。题目输入起到了误导的作用- -成功的认为是正方形,然而是矩形- -好吧。。题目描述的很清楚,人家说的很明白是矩形,输入的是行数,只怪自己咯╮(╯◇╰)╭ 白WA了好几次,给出题人跪了Orz。

思路呢,我和官方题解的不太一样~其实思路有很多啦。我的思路是用dfs的思想~ 也就是递归。我写了两个dfs函数,分别代表画红色和画蓝色的。(其实也能合并起来啦,不过还是分开写清楚一点。。) dfs函数里面的内容呢,用红色来举例子。首先传上去x,y的值,也就是坐标【我是从数组下标为1开始的,并不是0,后面会说原因】。首先写跳出条件,如果x>n或者y>n,那么return跳出。否则的话,我们就要去看右下角的那一个,也就是dfs(x+1,y+1)。那么怎么统计笔画数呢?因为G是R和B组成的,所以既能当成R也能当成B。那么我们想,只有当你当前dfs的这个位置是R或者G,并且下一个既不是R也不是G的时候,笔画数+1,所以把这句加进去加以判断就可以了,但是无论成立不成立,依然是要继续看右下角的那一个的,也就是说,无论什么情况,接下来都要进行dfs(x+1,y+1),除非越界跳出dfs。蓝色也是同样,只不过是看左下角的那一个,即dfs(x+1,y-1)。现在来解释一下为什么下标从0开始。因为首先我要把图画初始化成'.',也就是说,当你输入了图画之后,其实在数组里,图画周围是被'.'包围的。这样的话,就适用于上面的”只有当目前是R或G(或者B或G),而下一个不是“的判断了,因为如果下一个越界了,它是'.',适用于判断,然后再次dfs的时候,就会因为越界被return。

Painter

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 505    Accepted Submission(s): 246


Problem Description
Mr. Hdu is an painter, as we all know, painters need ideas to innovate , one day, he got stuck in rut and the ideas dry up, he took out a drawing board and began to draw casually. Imagine the board is a rectangle, consists of several square grids. He drew diagonally, so there are two kinds of draws, one is like ‘\’ , the other is like ‘/’. In each draw he choose arbitrary number of grids to draw. He always drew the first kind in red color, and drew the other kind in blue color, when a grid is drew by both red and blue, it becomes green. A grid will never be drew by the same color more than one time. Now give you the ultimate state of the board, can you calculate the minimum time of draws to reach this state.
 

Input
The first line is an integer T describe the number of test cases.
Each test case begins with an integer number n describe the number of rows of the drawing board.
Then n lines of string consist of ‘R’ ‘B’ ‘G’ and ‘.’ of the same length. ‘.’ means the grid has not been drawn.
1<=n<=50
The number of column of the rectangle is also less than 50.
Output
Output an integer as described in the problem description.
 

Output
Output an integer as described in the problem description.
 

Sample Input
  
2 4 RR.B .RG. .BRR B..R 4 RRBB RGGB BGGR BBRR
 

Sample Output
  
3 6
题目链接: HDU5319 Painter

下面上AC代码(15ms):

Problem : 5319 ( Painter )     Judge Status : Accepted
RunId : 14228528    Language : G++    Author : Moressette
Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char maze[55][55];
__int64 res=0;
int len;
int n;
void dfs1(int x,int y)
{
    if(x>n||y>len)
        return;
    else
    {
        if(maze[x][y]=='R' || maze[x][y]=='G')
        {
            if(maze[x+1][y+1]!='R' && maze[x+1][y+1]!='G')
                res++;
        }
    }
    dfs1(x+1,y+1);
}
void dfs2(int x,int y)
{
    if(x>n||y<1)
        return;
    else
    {
        if(maze[x][y]=='B' || maze[x][y]=='G')
        {
           if(maze[x+1][y-1]!='B' && maze[x+1][y-1]!='G')
                res++;
        }
    }
    dfs2(x+1,y-1);
}
int main()
{
    int T;
    string s;
    scanf("%d",&T);
    while(T--)
    {
        memset(maze,'.',sizeof(maze));
        scanf("%d",&n);
        res=0;
        int j=1;
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            len=s.length();
            for(int j=1;j<=len;j++)
            {
                maze[i][j]=s[j-1];
            }
        }
        for(int i=1;i<=n;i++)
            dfs1(i,1);
        for(int i=2;i<=len;i++)
            dfs1(1,i);
        for(int i=1;i<=n;i++)
            dfs2(i,len);
        for(int i=len-1;i>=1;i--)
            dfs2(1,i);
        printf("%I64u\n",res);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值