[白俊17779号]ガリマン・ドリン2
1.質問
ヒョン市の具在賢(ク・ジェヒョン)市長はこの数年間、ガリマン・デリンを通じて自分の党のために有利な選挙区を画定した.権力を牽制しなかった具在賢の権力行使は不当で、詩の名前まで再現詩に変えた.今度の選挙では、できるだけ公平に選挙区を画定するつもりです.
再生サイズN×N人格で表すことができます.グリッド内の各セルは領域を表し、r行c列の領域は(r,c)と表すことができる.領域は5つの選挙区に分割され、各選挙区は5つの選挙区のうちの1つを含む必要があります.選挙区には少なくとも1つの区が含まれ、1つの選挙区に含まれる区がつながっていなければならない.A区からB区までは、2つの区がつながっているそうです.中間通の隣接領域は0以上で、いずれも同じ選択領域に含まれる領域であるべきである.
選挙区を区切る方法は以下の通りです.
(d1, d2 ≥ 1, 1 ≤ x < x+d1+d2 ≤ N, 1 ≤ y-d1 < y < y+d2 ≤ N)
地域(r,c)の人口はA[r][c]であり、選挙区の人口は選挙区内のすべての地域に含まれる人口の総和である.選挙区を区分する方法では、人口が最も多い選挙区と人口が最も少ない選挙区の人口差の最大値を探し出す.
せいげんじょうけん
時間:1秒
メモリ:512 MB
5 ≤ N ≤ 20
1 ≤ A[r][c] ≤ 100
入力
1行目は再生時のサイズNを与える.
2行目からN行にはN個の整数がある.r行c列の整数はA[r][c]を表す.
しゅつりょく
1行目は、人口が最も多い選挙区と人口が最も少ない選挙区の最大差を出力します.
-キーワード
2.解答
初めてこの問題を見たとき、どうやって1秒で解決するか悩んでいました.
5番エリアに現れたすべての状況でしか考えられないのはブルトリーだけだ.
それ以外の方法は思い出せない.
さらに重要なのは、形が正方形ではなく、諸説ある方形なので、論理が思いつかないことです.
他の人の考えを知るために、グーグル圏を回った結果、本当に無知な答えが正解だった.
まず、この問題の核心は、すべての状況の数、すなわち5番地域を基準に評価することである.
5番エリアの警戒線
簡単に言えば、x,yは矩形の先端である.
d 1,d 2は左端長、右端長である.
つまり1番は左上、2番は右上、3番は左下、4番は右下です.
次のテストケースを見てみましょう.
8
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9 1
4 5 6 7 8 9 1 2
5 6 7 8 9 1 2 3
6 7 8 9 1 2 3 4
7 8 9 1 2 3 4 5
8 9 1 2 3 4 5 6
まず,我々が探索する部分は(x,y)を基準とするので,この部分を探索するだけでよい.
赤色部分では,特定のx,yを基準として左下から最大長さを探索する.
例(3,5)で試してみます.
(3,5)できるだけ左下をチェックします.
到着した場所を全部貯蔵する.
そして、最初の場所と訪問先を基準に右下の探索を行います.
到着した場所を順次保存する.
他の場所も同様に探索を行い,訪問した場所を保存する.
最初の赤いエリアから始めて、すべての場所で探求しました.
保存した内容を基准に、地域ごとに人口计算を行います.
たとえば、現在検索されている(3,5)部分を計算します.
これは先ほど探索して貯蔵した警戒線の末端です.
この部分を基準に1、2、3、4地区の人口を計算する.
計算する前に総人口を計算します.
それから地域人口を計算します.
そして第五区の人口を計算します.
総人口-(1号地区+2号地区区+3号地区区+4号地区区)が入手しやすい
このプロセスが繰り返されるすべての5番地域の状況の数だけでよい.本当に無知な方法だ.
3.ソースコード import sys
input = sys.stdin.readline
# 5번 지역구 구역 찾기
def find_divide(N,board,row,col):
half = [] # 위 그리고 왼쪽 점 저장
result = [] # 4점 저장
for d1 in range(1,N//2+1):
if 0 <= row+d1 < N and 0 <= col-d1 < N:
half.append([row+d1,col-d1])
else:
break
for d2 in range(1,N//2+1):
for i in half:
r,c = i
if 0 <= row+d2 < N and 0 <= col+d2 < N and 0 <= r+d2 < N and 0 <= c+d2 < N:
result.append([(row,col),(r,c),(row+d2,col+d2),(r+d2,c+d2)])
else:
break
return result
def city1(N,board,u,l): # 왼쪽 위 지역구 계산
people = 0
end = u[1]
for row in range(l[0]):
if row >= u[0]:
end -= 1
for col in range(end+1):
people += board[row][col]
return people
def city2(N,board,u,r): # 오른쪽 위 지역구 계산
people = 0
start = u[1]+1
for row in range(r[0]+1):
if row > u[0]:
start += 1
for col in range(start,N):
people += board[row][col]
return people
def city3(N,board,d,r): # 오른쪽 아래 지역구 계산
people = 0
start = r[1]
for row in range(r[0]+1,N):
for col in range(start,N):
people += board[row][col]
if start != d[1]:
start -= 1
return people
def city4(N,board,d,l): # 왼쪽 아래 지역구 계산
people = 0
end = l[1]
for row in range(l[0],N):
for col in range(end):
people += board[row][col]
if end < d[1]:
end += 1
return people
def solution(N,board):
divide = []
for row in range(N):
for col in range(1,N):
divide += find_divide(N,board,row,col)
people = 0
for i in board:
people += sum(i)
answer = people
for i in divide:
u,l,r,d = i
max_p,min_p = 0,1e9 # 최대 인구수와 최소 인구수
p1 = city1(N,board,u,l)
max_p = max(p1,max_p)
min_p = min(p1,min_p)
p2 = city2(N,board,u,r)
max_p = max(p2,max_p)
min_p = min(p2,min_p)
p3 = city3(N,board,d,r)
max_p = max(p3,max_p)
min_p = min(p3,min_p)
p4 = city4(N,board,d,l)
max_p = max(p4,max_p)
min_p = min(p4,min_p)
p5 = people - (p1+p2+p3+p4)
max_p = max(p5,max_p)
min_p = min(p5,min_p)
answer = min(answer,max_p-min_p)
return answer
if __name__ == "__main__":
N = int(input())
board = []
for _ in range(N):
board.append(list(map(int,input().split())))
print(solution(N,board))
4.後期
テスト出力を削除しなかったためエラーと判定されたが,このプロセスはのんびりしているようだ.
Breutforceは使いたくありませんが、標本が小さいので、先に解いてみたいと思います.
実際には、エンタープライズ・エンコード・テストでは表示されませんが、無知に試してみることもあります.
考えてみる必要があると思います.決してこのように出てはいけない.
Reference
この問題について([白俊17779号]ガリマン・ドリン2), 我々は、より多くの情報をここで見つけました
https://velog.io/@dark6ro/백준-17779번-게리맨더링-2
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import sys
input = sys.stdin.readline
# 5번 지역구 구역 찾기
def find_divide(N,board,row,col):
half = [] # 위 그리고 왼쪽 점 저장
result = [] # 4점 저장
for d1 in range(1,N//2+1):
if 0 <= row+d1 < N and 0 <= col-d1 < N:
half.append([row+d1,col-d1])
else:
break
for d2 in range(1,N//2+1):
for i in half:
r,c = i
if 0 <= row+d2 < N and 0 <= col+d2 < N and 0 <= r+d2 < N and 0 <= c+d2 < N:
result.append([(row,col),(r,c),(row+d2,col+d2),(r+d2,c+d2)])
else:
break
return result
def city1(N,board,u,l): # 왼쪽 위 지역구 계산
people = 0
end = u[1]
for row in range(l[0]):
if row >= u[0]:
end -= 1
for col in range(end+1):
people += board[row][col]
return people
def city2(N,board,u,r): # 오른쪽 위 지역구 계산
people = 0
start = u[1]+1
for row in range(r[0]+1):
if row > u[0]:
start += 1
for col in range(start,N):
people += board[row][col]
return people
def city3(N,board,d,r): # 오른쪽 아래 지역구 계산
people = 0
start = r[1]
for row in range(r[0]+1,N):
for col in range(start,N):
people += board[row][col]
if start != d[1]:
start -= 1
return people
def city4(N,board,d,l): # 왼쪽 아래 지역구 계산
people = 0
end = l[1]
for row in range(l[0],N):
for col in range(end):
people += board[row][col]
if end < d[1]:
end += 1
return people
def solution(N,board):
divide = []
for row in range(N):
for col in range(1,N):
divide += find_divide(N,board,row,col)
people = 0
for i in board:
people += sum(i)
answer = people
for i in divide:
u,l,r,d = i
max_p,min_p = 0,1e9 # 최대 인구수와 최소 인구수
p1 = city1(N,board,u,l)
max_p = max(p1,max_p)
min_p = min(p1,min_p)
p2 = city2(N,board,u,r)
max_p = max(p2,max_p)
min_p = min(p2,min_p)
p3 = city3(N,board,d,r)
max_p = max(p3,max_p)
min_p = min(p3,min_p)
p4 = city4(N,board,d,l)
max_p = max(p4,max_p)
min_p = min(p4,min_p)
p5 = people - (p1+p2+p3+p4)
max_p = max(p5,max_p)
min_p = min(p5,min_p)
answer = min(answer,max_p-min_p)
return answer
if __name__ == "__main__":
N = int(input())
board = []
for _ in range(N):
board.append(list(map(int,input().split())))
print(solution(N,board))
テスト出力を削除しなかったためエラーと判定されたが,このプロセスはのんびりしているようだ.
Breutforceは使いたくありませんが、標本が小さいので、先に解いてみたいと思います.
実際には、エンタープライズ・エンコード・テストでは表示されませんが、無知に試してみることもあります.
考えてみる必要があると思います.決してこのように出てはいけない.
Reference
この問題について([白俊17779号]ガリマン・ドリン2), 我々は、より多くの情報をここで見つけました https://velog.io/@dark6ro/백준-17779번-게리맨더링-2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol