AtCoder に登録したら解くべき精選過去問 10 問を VB.Net で解いてみた

実装リンク集 https://qiita.com/drken/items/6edb1c0542d4c3b7179c
問題一覧 https://abs.contest.atcoder.jp/assignments

私の実装 記事
Ruby (私家版) https://qiita.com/cielavenir/items/c0a45b6b87c411b60b93
Swift https://qiita.com/cielavenir/items/b90a94dce60a620fa2dc
C https://qiita.com/cielavenir/items/ee1e47b844d05dcfc66e
VB.Net https://qiita.com/cielavenir/items/7ddf5e9bac02daf72159
Pascal https://qiita.com/cielavenir/items/530270ac4affca435442
Perl https://qiita.com/cielavenir/items/4d16ba1be4ad6847a914

解答

例題 PracticeA

https://practice.contest.atcoder.jp/tasks/practice_1

C#と違って、VBはある程度の型変換は自動でやってくれます。

文字列を分割するには、Split()します。

0.vb
module practiceA
  sub Main(ByVal args() as String)
    dim a,b,c as integer
    dim s as string
    dim arr(2) as string
    a=Console.ReadLine()
    arr=Split(Console.ReadLine())
    b=arr(0):c=arr(1)
    s=Console.ReadLine()
    Console.Write(a+b+c)
    Console.WriteLine(" "+s)
  end sub
end module

第1問 ABC086A Product

https://abc086.contest.atcoder.jp/tasks/abc086_a

VBのIfは文でもあり演算子でもあります。

1.vb
module ABC086A
  sub Main(ByVal args() as String)
    dim a,b as integer
    dim arr(2) as string
    arr=Split(Console.ReadLine())
    a=arr(0):b=arr(1)
    Console.WriteLine(If(a*b mod 2 > 0,"Odd","Even"))
  end sub
end module

第2問 ABC081A Placing Marbles

https://abc081.contest.atcoder.jp/tasks/abc081_a

文字リテラルは"1"cのように作成します。

2.vb
module ABC081A
  sub Main(ByVal args() as String)
    dim s as string
    dim c,i as integer
    s=Console.ReadLine()
    c=0
    for i=0 to 2
      if s(i)="1"c then 'thenはなくても良い(以下では省略します)
        c=c+1
      end if
    next
    Console.WriteLine(c)
  end sub
end module

第3問 ABC081B Shift only

https://abc081.contest.atcoder.jp/tasks/abc081_b

arrの各要素に対し2で割ることが出来た回数の最小値です。
INF値として1<<29が使われていますが、2倍してオーバーフローしない中で簡潔に書ける数として競技プログラミングではよく使われます。

VBでは、整数除算は\です。また、剰余はmodです。

3.vb
module ABC081B
  sub Main(ByVal args() as String)
    dim i,n,x,r as integer
    r=1<<29
    n=Console.ReadLine()
    dim arr(n) as string
    arr=Split(Console.ReadLine())
    for i=1 to n
      dim r0 as integer
      r0=0
      x=arr(i-1)
      while (x mod 2)<1
        r0+=1
        x\=2
      end while
      if r>r0
        r=r0
      end if
    next
    Console.WriteLine(r)
  end sub
end module

第4問 ABC087B Coins

https://abc087.contest.atcoder.jp/tasks/abc087_b

500円玉と100円玉の枚数を全探索します。

VBのand/orは短絡評価を行いません。andalso/orelseを使いましょう。

4.vb
module ABC087B
  sub Main(ByVal args() as String)
    dim a,b,c,x,i,j,k,r as integer
    a=Console.ReadLine()
    b=Console.ReadLine()
    c=Console.ReadLine()
    x=Console.ReadLine()
    for i=0 to x\500
      for j=0 to (x-500*i)\100
        k=x-500*i-100*j
        if k mod 50=0 andalso c>=k\50 andalso a>=i andalso b>=j
          r+=1
        end if
      next
    next
    Console.WriteLine(r)
  end sub
end module

第5問 ABC083B Some Sums

https://abc083.contest.atcoder.jp/tasks/abc083_b

変数sは各i(j)を10で割れるだけ割って、その間に出た余りの和です。

5.vb
module ABC083B
  sub Main(ByVal args() as String)
    dim n,a,b,r,i,j,s as integer
    dim arr(3) as string
    arr=Split(Console.ReadLine())
    n=arr(0):a=arr(1):b=arr(2)
    r=0
    for i=1 to n
      s=0
      j=i
      while j>0
        s+=j mod 10
        j\=10
      end while
      if a<=s andalso s<=b
        r+=i
      end if
    next
    Console.WriteLine(r)
  end sub
end module

第6問 ABC088B Card Game for Two

https://abc088.contest.atcoder.jp/tasks/abc088_b

整数への変換はArray.ConvertAllで行っています。mono vbncではArray#Select(Linq)が使えないためです。また、関数のアドレスはaddressofで取ってくる必要があります。

降順でソートしたら、符号を切り替えながら足しこんでいきます。

6.vb
module ABC088B
  sub Main(ByVal args() as String)
    dim n,i,r,t as integer
    n=Console.ReadLine()
    dim arrs(n) as string
    dim arr(n) as integer
    arrs=Split(Console.ReadLine())
    arr=Array.ConvertAll(of string,integer)(arrs,addressof Integer.Parse)
    Array.Sort(arr)
    Array.Reverse(arr)
    r=0
    t=1
    for i=1 to n
      r+=t*arr(i-1)
      t=-t
    next
    Console.WriteLine(r)
  end sub
end module

第7問 ABC085B Kagami Mochi

https://abc085.contest.atcoder.jp/tasks/abc085_b

7.vb
imports System.Collections.Generic
module ABC085B
  sub Main(ByVal args() as String)
    dim n,i as integer
    dim m as new Dictionary(of integer,integer)
    'HashSetは.Net3.5以降のため使えません
    n=Console.ReadLine()
    for i=1 to n
      m(Console.ReadLine())=1
    next
    Console.WriteLine(m.Count)
  end sub
end module

第8問 ABC085C Otoshidama

https://abc085.contest.atcoder.jp/tasks/abc085_c

1000円札と5000円札の枚数を全探索します。

8.vb
module ABC085C
  sub Main(ByVal args() as String)
    dim n,y,i,j,k as integer
    dim arr(2) as string
    arr=Split(Console.ReadLine())
    n=arr(0):y=arr(1)
    for i=0 to n
      for j=0 to n-i
        k=n-i-j
        if i*1000+j*5000+k*10000=y
          Console.WriteLine("{0} {1} {2}",k,j,i)
          return
        end if
      next
    next
    Console.WriteLine("-1 -1 -1")
  end sub
end module

第9問 ABC049C Daydream

https://abc049.contest.atcoder.jp/tasks/arc065_a

文字列を逆にして比較していきます。C#と違って、StrReverse()で反転された文字列を得られます。

Substringする際は文字列長をチェックしなければなりません。

9.vb
module ABC049C
  sub Main(ByVal args() as String)
    dim T() as string = {"dream","dreamer","erase","eraser"}
    dim s as string
    dim i,c,l,k as integer
    for i=0 to 3
      T(i)=StrReverse(T(i))
    next
    s=StrReverse(Console.ReadLine())
    c=0
    l=s.Length
    while c<l
      k=-1
      for i=0 to 3
        if l-c>=T(i).Length andalso s.Substring(c,T(i).Length)=T(i)
          k=T(i).Length
          exit for
        end if
      next
      if k<0
        Console.WriteLine("NO")
        return
      end if
      c+=k
    end while
    Console.WriteLine("YES")
  end sub
end module

第10問 ABC086C Traveling

https://abc086.contest.atcoder.jp/tasks/arc089_a

dx+dyがdt以下かつdtとの偶奇が一致。

10.vb
module ABC086C
  sub Main(ByVal args() as String)
    dim i,n,t,x,y as integer
    dim arr(3) as string
    n=Console.ReadLine()
    t=x=y=0
    for i=1 to n
      arr=Split(Console.ReadLine())
      dim t0,x0,y0 as integer
      t0=arr(0):x0=arr(1):y0=arr(2)
      dim dt,dx,dy as integer
      dt=t0-t:dx=x0-x:dy=y0-y
      if dx+dy>dt orelse (dt-dx-dy) mod 2>0
        Console.WriteLine("No")
        return
      end if
      t=t0:x=x0:y=y0
    next
    Console.WriteLine("Yes")
  end sub
end module
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.