1. 動線安排
    1. 題目
    2. 解法

動線安排

動線安排

APCS歷屆

題目

看一下題目:
pic
url
看起來就是我們會有地圖並且我們要找出木樁的連線以及剩下幾個等等的。

解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# 學會座標可以多用幾個mark起來
# 模擬法
# 2d list
# 設座標
# 0代表沒東西 -1代表椿 1代表橫線 2代表縱線 3代表都有
# [[0, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0]] #用切片去做把中間的range都改成1
# 看到上下左右查是重點
# todo -> 設1, 2, 3判斷 easy
from sys import stdin

def match(now):
global many
if now[2] == 0:
add(now)
many += 1
else:
rm(now)
many += 1

def add(now):
global long
r, c = now[0], now[1]
list2[r][c] = -1

for i in range(c + 1, n):
if list2[r][i] == -1:
for k in range(c + 1, i):
if list2[r][k] == 0:
list2[r][k] = 1
elif list2[r][k] == 2:
list2[r][k] = 3
break

for i in range(c - 1, -1, -1):
if list2[r][i] == -1:
for k in range(i + 1, c):
if list2[r][k] == 0:
list2[r][k] = 1
elif list2[r][k] == 2:
list2[r][k] = 3
break

for i in range(r - 1, -1, -1):
if list2[i][c] == -1:
for k in range(i + 1, r):
if list2[k][c] == 0:
list2[k][c] = 2
elif list2[k][c] == 1:
list2[k][c] = 3
break

for i in range(r + 1, m):
if list2[i][c] == -1:
for k in range(r + 1, i):
if list2[k][c] == 0:
list2[k][c] = 2
elif list2[k][c] == 1:
list2[k][c] = 3
break

long = max(long, cou())

def rm(now):
global long
r, c = now[0], now[1]
list2[r][c] = 0

for i in range(c + 1, n):
if list2[r][i] == -1:
for k in range(c + 1, i):
if list2[r][k] == 1:
list2[r][k] = 0
elif list2[r][k] == 3:
list2[r][k] = 2
break

for i in range(c - 1, -1, -1):
if list2[r][i] == -1:
for k in range(i + 1, c):
if list2[r][k] == 1:
list2[r][k] = 0
elif list2[r][k] == 3:
list2[r][k] = 2
break

for i in range(r - 1, -1, -1):
if list2[i][c] == -1:
for k in range(i + 1, r):
if list2[k][c] == 2:
list2[k][c] = 0
elif list2[k][c] == 3:
list2[k][c] = 1
break

for i in range(r + 1, m):
if list2[i][c] == -1:
for k in range(r + 1, i):
if list2[k][c] == 2:
list2[k][c] = 0
elif list2[k][c] == 3:
list2[k][c] = 1
break

def cou():#計算有幾個被占據
longz = 0 #站存
for j in range(len(list2)):
for i in range(len(list2[0])):
if list2[j][i] != 0:
longz += 1
return longz


#how about 2d list
#m, n, h = 3, 4, 4
m, n, h = map(int, stdin.readline().split())
#list1 = [[0, 1, 0], [2, 1, 0], [2, 3, 0], [2, 1, 1]] #input()
#list1 = [[0, 3, 0], [0, 9, 0], [0, 4, 0], [0, 4, 1]]
list1 = []
for i in range(h):
list1.append(list(map(int,stdin.readline().split())))
#list1 = [list(map(int, stdin.readlines().split()))]
list2 = [[0 for i in range(n)]for i in range(m)] #2d map
many = 0
#print(list2)
long = 0
for i in list1:
match(i)
#print(list2)
#print(list2)
print(long)
a = 0
#print(list2)
for j in range(len(list2)):
for i in range(len(list2[0])):
if list2[j][i] != 0 :
a += 1
print(a)

我的想法就是不管在加入木樁時還是刪掉我們都上下左右跑一次,直到我們找到木樁我們在往前推來回去改成1之類的,那為甚麼說之類呢?因為我們會用1, 2, 3來標註,分別是橫線, 直線, 重疊,這樣我們刪掉的同時才不會一次刪到兩條。