画家问题

编程题#1: 画家问题

描述

有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使。当他用画笔涂画第(i, j)个位置的砖时, 位置(i-1, j)、 (i+1, j)、 (i, j-1)、 (i, j+1)上的砖都会改变颜色。请你帮助Bob计算出最少需要涂画多少块砖,才能使所有砖的颜色都变成黄色。

                                 

                                

输入

第一行是个整数t(1≤t ≤20),表示要测试的案例数。然后是t个案例。每个案例的首行是一个整数n (1≤n ≤15),表示墙的大小。接下来的n行表示墙的初始状态。每一行包含n个字符。第i行的第j个字符表示位于位置(i,j)上的砖的颜色。“w”表示白砖,“y”表示黄砖。

输出

每个案例输出一行。如果Bob能够将所有的砖都涂成黄色,则输出最少需要涂画的砖数,否则输出“inf”




Analysis:

枚举墙的第一行所有列的涂画情况,依此推断下一行的的涂画情况(使每行的墙都被涂画成黄色)直到最后一行,然后check最后一行的墙是否能被涂成黄色。


实现代码如下:


#include<iostream>  
using namespace std;  
  
int wallColor[16][17] = {0};  
int paint[16][17] = {0};  
  
int trys(int &wallSize){  
    int row,col;//画板的行和列  
    /*根据画板颜色和周围paint颜色值判断下一行paint的颜色值*/  
    for(row=1; row<wallSize;row++){  
        for(col=1;col<=wallSize;col++){  
            paint[row+1][col]= (wallColor[row][col]+paint[row-1][col]+  
                                paint[row][col-1]+paint[row][col]+paint[row][col+1])%2;   
        }  
    }  
  
    //判断最后一行能否被画成黄色  
    for(col=1;col<=wallSize;col++){  
        if(wallColor[wallSize][col]!=(paint[wallSize-1][col]+paint[wallSize][col-1]  
           +paint[wallSize][col]+paint[wallSize][col+1])%2){  
           return 400;  
           }  
    }  
  
    //计算所需的次数  
    int steps=0;  
    for(row=1;row<=wallSize;row++){  
        for (col=1;col<=wallSize;col++){  
            if(paint[row][col]==1){  
                steps++;  
            }  
        }  
    }  
    return steps;  
}  
  
  
//枚举第一行的所有情况  
int enumerate(int &wallSize){  
    int minsteps=400;  
    int steps=0;  
    while(paint[1][wallSize+1]<1){  
        steps=trys(wallSize);  
        if (steps<minsteps){  
            minsteps=steps;  
        }  
        paint[1][1]++;  
        int c=1;  
        while(paint[1][c]>1){  
            paint[1][c]=0;  
            c++;  
            paint[1][c]++;  
        }  
    }  
    return minsteps;  
}  
  
  
int main(){  
    int t,n,c,r;  
    int minsteps;  
    cin>>t;  
    for (int k=0;k<t;k++){  
  
        //初始化画板颜色  
        for(r=0;r<16;r++){  
            for(c=0;c<17;c++){  
                wallColor[r][c]=0;  
                paint[r][c]=0;  
            }  
        }  
  
        //输入颜色并将颜色转换为数字 0 or 1  
        cin>>n;  
        for(r=1;r<n+1;r++){  
            for(c=1;c<n+1;c++){  
                char color;  
                cin>>color;  
                wallColor[r][c]=color=='y'?0:1;  
            }  
        }  
  
        minsteps=enumerate(n);  
        if (minsteps==400){  
            cout<<"inf"<<endl;  
        }  
        else{  
            cout<<minsteps<<endl;  
        }  
  
    }  
}  

Python版本:


wallColor = [[0 for i in range(17)] for i in range(16)]  
paint = [[0 for i in range(17)] for i in range(16)]  
  
def trys(wallSize):  
    for row in range(wallSize)[1:]:  
        for col in range(wallSize+1)[1:]:  
            paint[row+1][col] = (wallColor[row][col] + paint[row-1][col] + paint[row][col-1] +  
                                 paint[row][col] + paint[row][col+1])%2  
  
    for col in range(wallSize+1)[1:]:  
        if (wallColor[wallSize][col]!=(paint[wallSize-1][col]+paint[wallSize][col-1]  
           +paint[wallSize][col]+paint[wallSize][col+1])%2):  
            return 400  
  
    steps = 0  
    for row in range(wallSize+1)[1:]:  
        for col in range(wallSize+1)[1:]:  
            if paint[row][col] == 1:  
                steps+=1  
    return steps  
  
  
def enumerate(wallSize):  
    minsteps = 400  
    steps = 0  
    while(paint[1][wallSize]<1):  
        steps = trys(wallSize)  
        if (steps<minsteps):  
            minsteps = steps  
        paint[1][1] += 1  
        c = 1  
        while(paint[1][c]>1):  
            paint[1][c] = 0  
            c += 1  
            paint[1][c]+=1  
  
    return minsteps  
  
def __main__():  
    t = int(input())  
    for k in range(t):  
        for r in range(16):  
            for c in range(17):  
                wallColor[r][c] = 0  
                paint[r][c] = 0  
  
        n = int(input())  
        for r in range(n+1)[1:]:  
            for c in range(n+1)[1:]:  
                color = chr(input())  
                if color == 'y':  
                    wallColor[r][c] = 0  
                else:  
                    wallColor[r][c] = 1  
  
        minsteps = enumerate(n)  
        if (minsteps == 400):  
            print ('inf')  
        else:  
            print minsteps  
  
__main__()



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
画家算法和Z缓存算法都是用来解决三维图形显示时的遮挡问题算法,但是它们的实现方式和效率有所不同。 画家算法,也称为排序算法,是一种按照深度排序的遮挡处理算法。它通过对场景中的所有多边形按照深度排序,并从前往后渲染,实现遮挡关系的确定。具体实现过程是先将所有多边形按照深度排序,然后按照顺序进行绘制,每次绘制时都会检查当前像素点的深度值与已绘制部分的深度值进行比较,如果当前像素点在已绘制部分的后面,则跳过不绘制,否则进行绘制。虽然画家算法能够处理复杂的场景,但是它的效率较低,因为每次绘制都需要进行深度值的比较。 而Z缓存算法,也称为深度缓存算法,是一种利用缓存来存储深度信息的遮挡处理算法。它通过先将场景中的所有多边形按照深度排序,并将深度值存储在缓存中,在渲染时,每次绘制一个像素时,都会将当前像素点的深度值与缓存中的深度值进行比较,如果当前像素点在已绘制部分的后面,则跳过不绘制,否则进行绘制,并更新缓存中的深度值。由于Z缓存算法利用缓存来存储深度信息,因此它的效率较高,但是需要消耗较大的内存空间。 综上所述,画家算法和Z缓存算法都是用来解决三维图形显示时的遮挡问题算法,但是它们的实现方式和效率有所不同。画家算法通过深度排序来实现遮挡关系的确定,效率较低;而Z缓存算法利用缓存来存储深度信息,效率较高,但是需要消耗较大的内存空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值