dポイントプレゼントキャンペーン実施中!

[問題]
p 人のグループ A , q 人のグループ B , r 人のグループ C があります。各グループのメンバーにはそれぞれ番号がつけられており、 A グループの i 番目の人は B グループの j 番目の人に仕事を任せ、 B グループの j 番目の人は与えられた仕事を C グループの k 番目の人に任せます。すると結局、 A グループの i 番目の人の仕事をするのは C グループの k 番目の人だということになります。

鈴木君は A グループの各人の仕事を結局 C グループの誰が行うことになるのか知りたがっています。 A グループの人のそれぞれが最終的に C グループの誰に仕事を頼むことになるのかを、 A グループの人の番号が小さい順に p 行出力してください。

p q r
i_1 j_1
...
i_p j_p
j'_1 k_1
...
j'_q k_q

1 行目には A グループ、 B グループ、 C グループのそれぞれの人数 p , q , r が半角スペース区切りで与えられます。
2 行目から (p + 1) 行目までは A グループの人の番号とその人が仕事を頼む B グループの人の番号 i_a, j_a (1 ≤ a ≤ p) が半角スペース区切りで、 (p + 2) 行目から (p + q + 2) 行目までは B グループの人の番号とその人が仕事を頼む C グループの人の番号 j’_b , k_b (1 ≤ b ≤ q) が半角スペース区切りで与えられます。



入力例1 出力例1
2 2 2 1 2
2 1 2 1
1 2
1 1
2 2

入力例2 出力例2
2 3 4 1 3
1 3 2 4
2 1
2 3
3 3
1 4



[解答例]
a,b,c=map(int,input().split())

# print(a)

AB={}
BC={}


for _ in range(a):
i,j=map(int,input().split())
AB[i]=j


for _ in range(b):
j,k=map(int,input().split())
BC[j]=k

AC={}


for i in range(1,a+1):        →①
# 範囲について
AC[i]=BC[AB[i]]         →②
#ここの意味がわからない

print(AC[i])

ans=sorted(AC.items(),key=lambda x:x[0])

for n in range(a):
i,k=ans[n]
print(i,k)

質問
1.解答例の①の範囲が分かりませんでした。どのような仕組みでこの範囲にしているのか分かりませんでした。
2.②も、どのような仕組みになっているのか分かりませんでした。
AB[i]=j などはi,j=2,2   2,4   5,6の時
{2:2,2:4,5:6}となるのは分かります。

Pythonに詳しい方、上記の質問に回答していただけると助かります。
よろしくお願い致します。

A 回答 (3件)

1.


> A グループの i 番目の人は B グループの j 番目の人に仕事を任せ

と言っているんだから、i, j, kは1から始まるからじゃないですか。だって、0番目っておかしいですよね。
iは1からa+1までの通し番号になるはずです。

2.
AC[i]=BC[AB[i]]

ようは、i -> j -> kというリンクを作ったあと、jをすっ飛ばしてi -> kというリンクを作りたいわけです。
AB[i]にはAのiさんに依頼されたBのjさんが入ります。BC[j]にはBのjさんに依頼されたCのkさんが入ります。
したがって、Aのiさんに依頼されたCのkさんはBC[AB[i]]となります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
1は補足も含めて理解できました。ありがとうございます。

2についてなんですが、流れは分かるのですが、AB[BC[i]]でもいいのではないかと思うくらい、あまりプログラムの書き方が理解できていない状況です。
アドバイスがあればアドバイスして欲しいです。

お礼日時:2020/07/04 22:24

> 流れは分かるのですが、AB[BC[i]]でもいいのではないかと思うくらい、あまりプログラムの書き方が理解できていない状況です。



具体的にどのあたりが分かりにくいのかわかりませんが、AB[BC[i]]に関しては...

まず、リストの名前がどういう基準でつけられているかをしっかり把握する。
リストAB, BC, ACはそれぞれ2文字であらわされているが、その一つ目の文字は依頼する人が所属するグループ、二つ目の文字は依頼される人が所属するグループです。リストのインデックスは一つ目の文字グループに所属する人で、リストの要素(中身)は二つ目の文字グループに所属する人です。たとえば、BC[a]そのものはCに所属する人を要素としてもち、インデックスのaはBに所属する人となる。
最終的に求めたいものはAとCの関係であり、AC[i]です。再度繰り返すけど、iはAに属して、AC[i]の要素そのものはCに属する。

以上を踏まえると、
あなたのいうAB[BC[i]]が持っている要素の値はBに属する人となるから、問題が求めているもの(Cに属する人)とは違ってきます。さらにBCのインデックスはBに属する人であるべきで、BC[i]としてAの人iさんをインデックスとして持ち込むのは論理的におかしいですね。



AC[i]の話に戻ります。
ここからは、Cのほうから逆にたどっていく。

まずBC[j]によりBのjさんに対するCのkさんがわかります。
k = BC[j]

次にjさん(Bグループの人)をAの人iさんと関連付ける必要がある。これは j = AB[i]で、AのiさんとBのjさんが関連付けられます。
j = AB[i]

上の二つの式から、k = BC[j] = BC[AB[i]]となって、Aのiさんと、Cのkさんを関連付けることができる。




プログラムは慣れですから、ある程度場数を踏むと自然にこういうのは理解できるようになります。
    • good
    • 0
この回答へのお礼

本当に回答ありがとうございます。
おかげさまで、二つの式から導く方法で納得できました。
また、言葉の定義とかも曖昧でしたので、しっかり理解することができました。

これからも、どんどんプログラム書いていきたいと思います。
また、機会があれば是非宜しくお願い致します。

お礼日時:2020/07/05 10:33

#1ですが、間違えました。


「iは1からa+1までの通し番号になるはずです」は間違いです。
iは1からaまでの通し番号になるはず、が正しい。


もしかして、range(1, a+1)が1からa+1と思ってませんか? range(x, y)ではyは含まず、xからy-1を表現します。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!