Processing math: 0%

2020年2月21日金曜日

TopCoder Single Round Match 776

 今年はじめてEasyがACできた! と思ったらシステムテストで落ちて0完。単純なミスだったのでもったいない。

Div1 Easy EncloseArea

 斜めに線を引いて、指定された面積の多角形を作る問題。

 最小の正方形の面積は2で、その一辺を削って、隣に膨らませれば面積は+2される。
 なので、まず50*50の方眼紙の対角線上に斜めに長い長方形を作り、それを一つずつ膨らませる実装をした。一々、辺を増やして減らして……としているためかなり汚い実装になってしまった。

 そして、一番最初、面積2から始めてそこから求める面積まで増やしていく……というように書いてしまったため、面積2のときそのまま出力するのを忘れてしまってシステムテスト落ち。

・最小値・最大値で通るかチェック

 はきちんとしなくてはいけませんね。

 kmjpさんのブログの記事のように頂点に着目すればもっと簡単に実装できます。

 コンテスト中のコードを修正したものなので非常に読みにくいのですが、一応ACしたコードを載せておきます(載せるか迷ったのですが、ACした証拠として)。

  1. class EncloseArea():
  2. def enclose(self, A):
  3. if A%2!=0:
  4. return tuple()
  5. if A>2402:
  6. return tuple()
  7.  
  8. ANS=[["."]*50 for i in range(50)]
  9.  
  10. ANS[0][0]="/"
  11. ANS[0][1]="\\"
  12. ANS[1][0]="\\"
  13. ANS[1][1]="/"
  14. S=2
  15.  
  16. for i in range(1,49):
  17. if S==A:
  18. break
  19. ANS[i][i]="."
  20. ANS[i+1][i+1]="/"
  21. ANS[i][i+1]=ANS[i+1][i]="\\"
  22. S+=2
  23.  
  24. if S==A:
  25. A=[]
  26.  
  27. for ans in ANS:
  28. A.append("".join(ans))
  29.  
  30. return tuple(A)
  31.  
  32. NOWP=[0,1]
  33. NOWM=[1,0]
  34.  
  35. def rewrite1(x,y):
  36. if ANS[x-1][y]==".":
  37. ANS[x-1][y]="/"
  38. else:
  39. ANS[x-1][y]="."
  40.  
  41. ANS[x][y]="."
  42. ANS[x-1][y+1]="\\"
  43. ANS[x][y+1]="/"
  44.  
  45. def rewrite2(x,y):
  46. if ANS[x][y-1]==".":
  47. ANS[x][y-1]="/"
  48. else:
  49. ANS[x][y-1]="."
  50.  
  51. ANS[x][y]="."
  52. ANS[x+1][y-1]="\\"
  53. ANS[x+1][y]="/"
  54. while True:
  55. x,y=NOWP
  56. if 0<=x-1<50 and 0<=y+1<50:
  57. rewrite1(x,y)
  58. S+=2
  59. NOWP[0]+=1
  60. NOWP[1]+=1
  61.  
  62. if NOWP[0]==49 or NOWP[1]==49:
  63. MIN=min(NOWP)
  64. NOWP[0]-=MIN
  65. NOWP[1]-=MIN
  66. NOWP[1]+=2
  67.  
  68. if S==A:
  69. break
  70.  
  71. x,y=NOWM
  72. if 0<=x+1<50 and 0<=y-1<50:
  73. rewrite2(x,y)
  74. S+=2
  75. NOWM[0]+=1
  76. NOWM[1]+=1
  77.  
  78. if NOWM[0]==49 or NOWM[1]==49:
  79. MIN=min(NOWM)
  80. NOWM[0]-=MIN
  81. NOWM[1]-=MIN
  82. NOWM[0]+=2
  83.  
  84. if S==A:
  85. break
  86.  
  87. if S==A:
  88. A=[]
  89.  
  90. for ans in ANS:
  91. A.append("".join(ans))
  92.  
  93. return tuple(A)

Div1 Medium StringRings

 kmjpさんのブログの記事を参考にして通した。

 両端赤、両端緑、両端が異なる、のそれぞれのひもの個数をr, g, bとおき、実際に本数を求めてみよう、と式を書いてみたら、自然と再帰的に書け(多分、C++なら再帰のままでもACできる?)、それを整理したらさらに簡単な式になった。

・とりあえず立式

 さえしていればそれほど難しくなかった気がする。

 コンテスト本番では、Easyに時間を取られてしまったので解けなかったけど、ACしたい問題でしたね~。

 以下、ACしたコード。

  1. class StringRings():
  2. def expectedRings(self, A, B):
  3. ANS=0
  4. for i in range(A):
  5. ANS+=1.0/(2*i+1)
  6.  
  7. for i in range(B):
  8. ANS+=1.0/(A*2+i+1)
  9.  
  10. return ANS

0 件のコメント:

コメントを投稿