ZOJ1002 python AC

4 篇文章 0 订阅

ZOJ1002:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364501

Fire Net

Time Limit: 2000 msMemory Limit: 65536 KB

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

 

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.

The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a '.' indicating an open space and an uppercase 'X' indicating a wall. There are no spaces in the input file.

For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.

Sample input:

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0

Sample output:

5
1
5
2
4

翻译:(由于直接复制腾讯翻译出来的结果,可能存在句意不明,看不懂的地方之间看上面原文,自己译)

火力网

时限:2000毫秒内存限制*65536 KB

假设我们有一个正方形的城市,街道笔直。一个城市的地图是一个正方形板,有n行和n列,每一列代表一条街或一堵墙。

堡垒是一座小城堡,有四个可以射击的开口。这四个开口分别面向北、东、南和西。每个开口都会有一支机枪射击。

在这里,我们假设一颗子弹是如此强大,它可以穿越任何距离,在途中摧毁一个堡垒。另一方面,墙是如此坚固,可以阻止子弹。

我们的目标是把许多一座城市里的路障,这样就不会有两个人互相残杀。堡垒的配置是合法但除非至少有一堵墙将其隔开,否则地图上的同一水平列或垂直柱上不得有两个障碍物。在这个问题上,我们将考虑小广场城市(最多4x4),其中包含子弹无法穿过的墙壁。

下图显示同一板的五幅图片。第一张图片是空板,第二张和第三张图片显示合法配置,第四张和第五张图片显示非法配置。对于这个板,合法配置中的最大路障数为5;第二张图片显示了一种方法,但还有其他几种方法。

 

您的任务是编写一个程序,给出地图的描述,计算出可以在城市中合法配置的最大路障数量。

输入文件包含一个或多个映射描述,后面是一个包含数字0的行,该数字表示文件的结尾。每个地图描述从包含正整数的一行开始。n这就是城市的大小;n最多4下n每行描述地图的一行,并带有“.“表示开放空间和大写字母”X“指一堵墙。输入文件中没有空格。

对于每个测试用例,输出一行,其中包含可以在合法配置中放置在城市中的最大路障数量。

样本输入:

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0

样本输出:

5
1
5
2
4

代码:

# -*- coding: utf-8 -*-
"""
@Author: ChenCheng
@Date: 2020-05-20 14:06:27
@LastEditTime: 2020-05-21 11:14:58
@Description: 暴搜DFS
"""
from math import *

def bo(c):
    if c == '.':
        return True
    else:
        return False

def dfs(num):
    b = []
    n = num
    
    for i in range(0, len(a)):
        for j in range(0, len(a)):
            if bo(a[i][j]):
                a[i][j] = 'x'
                b.append([i, j])
                
                h = i + 1
                while h < x and (a[h][j] == '.' or a[h][j] == 'x'):
                    if a[h][j] == '.':
                        b.append([h, j])
                    a[h][j] = 'x'
                    h += 1
                
                h = i - 1
                while h >= 0 and (a[h][j] == '.' or a[h][j] == 'x'):
                    if a[h][j] == '.':
                        b.append([h, j])
                    a[h][j] = 'x'
                    h -= 1

                h = j + 1
                while h < x and (a[i][h] == '.' or a[i][h] == 'x'):
                    if a[i][h] == '.':
                        b.append([i, h])
                    a[i][h] = 'x'
                    h += 1
                
                h = j - 1
                while h >= 0 and (a[i][h] == '.' or a[i][h] == 'x'):
                    if a[i][h] == '.':
                        b.append([i, h])
                    a[i][h] = 'x'
                    h -= 1

                n = max(dfs(num+1), n)

                for h in b:
                    a[h[0]][h[1]] = '.'
    return n    


if __name__ == "__main__":
    while True:
        x = int(input())
        if x:
            a = []
            for i in range(0, x):
                y = input()
                b = list(y)
                a.append(b)
            num = dfs(0)
            print(num)
        else:
            break

 

请忽视丑陋的命名,没遵守规则随意命名了

用python打深搜可真的是,一言难尽,由于python绑定的是地址,用列表代替数组,在函数内改变列表内的存值会直接反馈到原数组中,所以复杂了很多,还另外添加了一个列表b来记录数组改变的路径,用来回溯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值