ねむーの日記~AtCoderな日々~

福岡に住むプログラミング好きのブログです!

AtCoder Beginner Contest 128 A - Apple Pie

久しぶりの更新となりました、ねむーです。

今回はAtCoder(https://atcoder.jp/contests/abc/tasks/abc128_a)にて開催されました、AtCoder Beginner Contest 128 A問題「A - Apple Pie」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

林檎が A 個、林檎の欠片が P 個あります。

林檎 1 個は、砕くことで林檎の欠片 3 個になります。また、林檎の欠片 2 個を鍋で煮込むことで、アップルパイが 1 個作れます。

今ある材料で作れるアップルパイの最大数を求めてください。

2.制約

入力は全て整数である。

  • 0 ≤ A , P ≤ 100

3.入力例

  • 入力
1 3
  • 出力
3

3 つある林檎の欠片のうち 2 つを鍋で煮込むことで、まず 1 つのアップルパイを作ることができます。

林檎の欠片が 1 つ残りますが、これと、 1 つある林檎を砕いて新しく得た 3 つの林檎の欠片から、さらに 2 つのアップルパイを作れます。

4.初見の感想

  • 「アップルパイ数=(3*リンゴ数+リンゴ欠片)/2」で求められる

    5.学びポイント

  • 簡単な計算は出力部分(WriteLine)で計算すると簡潔

    6.コードと簡単な解説

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        string[] input = Console.ReadLine().Split(' ');
        int A = int.Parse(input[0]);
        int P = int.Parse(input[1]);
        Console.WriteLine((3 * A + P) / 2);
    }
 }

7.最後に

綺麗にコードが書けると気持ちいいですね!

AtCoder Beginner Contest 127 A - Ferris Wheel

最近暑くなってきましたね、ねむーです。

今回はAtCoder(https://atcoder.jp/contests/abc)にて開催されました、AtCoder Beginner Contest 127 A問題「A - Ferris Wheel」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

A 歳の高橋君が観覧車に乗ろうとしています。

この観覧車は、 13 歳以上が乗るには B 円 ( B は偶数) かかりますが、 6 歳以上 12 歳以下の人はその半額で乗ることができ、 さらに 5 歳以下の人は無料で乗ることができます。

高橋君が観覧車に乗るには何円かかるかを求めてください。

2.制約

  • 0 ≤ A ≤ 100
  • 2 ≤ B ≤ 1000
  • B は偶数

3.入力例

  • 入力
30 100
  • 出力
100

4.初見の感想

  • if文で条件分岐出力

5.コードと簡単な解説

using System;

class Program
{
    static void Main(string[] args)
    {
        string[] input = Console.ReadLine().Split(' ');
        int A = int.Parse(input[0]);
        int B = int.Parse(input[1]);
        if (A >= 13) { Console.WriteLine(B); }
        else if(A<=5){ Console.WriteLine(0); }
        else { Console.WriteLine(B/2); }
    }
}

6.最後に

最初5歳以下の分岐を忘れてたので、早とちりには気を付けましょう。

AtCoder Beginner Contest 126 C - Dice and Coin

久しぶりのブログ更新、ねむーです。

今回はAtCoder(https://atcoder.jp/contests/abc126)にて開催されました、AtCoder Beginner Contest 126 C問題「C - Dice and Coin」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

すぬけ君は 1 〜 N の整数が等確率で出る N 面サイコロと表と裏が等確率で出るコインを持っています。すぬけ君は、このサイコロとコインを使って今から次のようなゲームをします。

まず、サイコロを 1 回振り、出た目を現在の得点とする。

得点が 1 以上 K − 1 以下である限り、すぬけ君はコインを振り続ける。表が出たら得点は 2 倍になり、裏が出たら得点は 0 になる。

得点が 0 になった、もしくは K 以上になった時点でゲームが終了する。このとき、得点が K 以上である場合すぬけ君の勝ち、 0 である場合すぬけ君の負けである。

N と K が与えられるので、このゲームですぬけ君が勝つ確率を求めてください。

2.制約

  • 1 ≤ N ≤ 105
  • 1 ≤ K ≤ 105
  • 入力はすべて整数

3.入力例

  • 入力
100000 5
  • 出力
0.999973749998

4.初見の感想

  • 毎回確率の係数を計算したくない
  • 最初の数字がK以上なら無条件クリアとなる
  • 確率の係数0.5をM回掛けるかは「Kを2で少なくともM回割れば最初の初期値以下になる」という条件で求められる(最初の初期値をどんどん2倍にするゲームなので…)

5.学びポイント

  • 0.5を掛け算する回数は初期値が大きいほど少ないのでfor文をNから下に回します
  • Nの値がKよりとても小さい場合、最初の0.5を何回掛けるかを出すのにループを回してしまう→ループを回さない工夫が必要
  • Nで割る処理は値を非常に小さくしてしまうため、最後に行う(誤差を防止するため)

6.コードと簡単な解説

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
//入力
        string[] input = Console.ReadLine().Split(' ');
        double N = double.Parse(input[0]);
        double K = double.Parse(input[1]);
        double ans = 0;
        double num = 1;
//計算回数の少ないNからループを行う
        for(double i=N;i>0; i--)
        {
            if (i < K) {
      //係数は順番に*0.5ずつ小さくなる性質がある
                num *= 0.5;
                K = K / 2;
            }
            if(i>=K){
                ans += num;
            }
            //ループを止める処理
            if (ans == 0) { i = N + 1; }
        }
        //Nで割る処理は最後に行う
        ans = ans / N;
        Console.WriteLine(ans);
    }
}

7.最後に

解けましたが1時間ほどかかってしまったので、鍛錬が必要です(^-^;

Tenka1 Programmer Beginner Contest 2019 C - Stones

平成最後の一週間と聞いてビックリしました、ねむーです。

今回はAtCoder(https://atcoder.jp/contests/tenka1-2019-beginner)にて開催されました、Tenka1 Programmer Beginner Contest 2019 C問題「C - Stones」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

N 個の石が一列に並んでおり、すべての石は白か黒で塗られています。 石の状態は長さ N の文字列 S で表され、 S の i 文字目が" . "のとき左から i 個目の石が白であり、"#" のとき左から i 個目の石が黒であることを表します。

高橋君は、 0 個以上の石の色を黒または白に変更し、黒い石のすぐ右に白い石があるような箇所がないようにしたいです。 色を変更する必要のある石の個数の最小値を求めてください

2.制約

  • 1 ≤ N ≤ 2 × 105
  • S は "." , "#" のみからなる長さ N の文字列である

3.入力例

  • 入力
5
#.##.
  • 出力
2

4.初見の感想

  • 白と黒の二種類しかないので、最終形が予想できそう? →「All白」or「All黒」or「白連続→黒連続の順」という3パターン

5.学びポイント

  • 厄介なのはどこで白連続と黒連続の境界を設けるか、という問題

→最初に白黒の総数を計算しておくことで、ループの途中でも後ろに続く列の中に何個白や黒があるかがわかる!

  • 「境界の左側にある黒色の数+境界の右側にある白色の数」が変更する回数となる

6.コードの簡単な解説

  • まず、入力の値のパースを行う
        string input = Console.ReadLine();
        int N = int.Parse(input);
        input = Console.ReadLine();
        char[] S= input.ToCharArray();
  • 白色の総数を計算
        int white_all = 0;
        int black = 0;
        for(int i = 0; i < N; i++)
        {
            if (S[i] == '.') { white_all++; }
        }
  • 白や黒のみの場合の例外処理、白や黒のカウンタの用意
        int ans = white_all;
        int counter = 0;
        int white = white_all;
        if (white_all == S.Length || white_all == 0) ans = 0;
  • 境界の左の黒の数と教会の右にある白の数をカウント
        else
        {
            for (int i = 0; i < N; i++)
            {
                if (S[i] == '#') { black++; }
                else { white--; }
                counter = black + white;
                if (counter < ans) { ans = counter; }
            }
        }
        Console.WriteLine(ans);

7.全コード

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        string input = Console.ReadLine();
        int N = int.Parse(input);
        input = Console.ReadLine();
        char[] S= input.ToCharArray();
        int white_all = 0;
        int black = 0;
        for(int i = 0; i < N; i++)
        {
            if (S[i] == '.') { white_all++; }
        }
        int ans = white_all;
        int counter = 0;
        int white = white_all;
        if (white_all == S.Length || white_all == 0) ans = 0;
        else
        {
            for (int i = 0; i < N; i++)
            {
                if (S[i] == '#') { black++; }
                else { white--; }
                counter = black + white;
                if (counter < ans) { ans = counter; }
            }
        }
        Console.WriteLine(ans);
    }
}

8.最後に

本番解けなかったのが悔しいですね…

Tenka1 Programmer Beginner Contest 2019 A - On the Way

朝から研究室の荷物探しにより疲労がMAXのねむーです。

今回はAtCoder(https://atcoder.jp/contests/tenka1-2019-beginner/tasks/tenka1_2019_a)にて開催されました、Tenka1 Programmer Beginner Contest 2019 A問題「A - On the Way」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

数直線上に家 1 , 2 , 3 があり、それぞれのある座標は A , B , C です。 家 1 から家 2 まで寄り道をせずにまっすぐ向かう途中で家 3 のある座標を通る場合は Yes を、そうでない場合は No を出力してください。

2.制約

  • 0 ≤ A , B , C ≤ 100
  • A , B , C は相異なる整数である

3.入力例

  • 入力
31 41 59
  • 出力
No

4.初見の感想

  • AとBの最大値と最小値の間にCが含まれているかを判定
  • A<B&&A<C&&C<B||A>B&&A>C&&C>BよりもMax.Min関数を使う方が簡潔!

5.全コード

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        string[] input = Console.ReadLine().Split(' ');
        int A = int.Parse(input[0]);
        int B= int.Parse(input[1]);
        int C= int.Parse(input[2]);
        if (Math.Min(A, B) < C && Math.Max(A, B) > C) { Console.WriteLine("Yes"); }
        else { Console.WriteLine("No"); }
        
    }
}

6.最後に

5分ぐらいで解けたのでよかったです(^^)

Tenka1 Programmer Beginner Contest 2019 B - *e**** ********e* *e****e* ****e**

休日に腰を痛めてしまいました、ねむーです。

今回はAtCoder(https://atcoder.jp/contests/tenka1-2019-beginner)にて開催されました、Tenka1 Programmer Beginner Contest 2019 B問題「B - e e *ee *e」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

英小文字からなる長さ N の文字列 S と整数 K が与えられます。 S の K 番目の文字と異なる文字全てを * で置き換えてできる文字列を出力してください。

2.制約

  • 1 ≤ K ≤ N ≤ 10
  • S は英小文字からなる長さ N の文字列である
  • N , K は整数である

3.入力例

  • 入力
9
education
7
  • 出力
******i**

4.初見の感想

  • 文字列を前からループかけて、K番目の指定した文字との文字列比較で表示を変更すればよい

5.学びポイント

  • 「K番目」は1から始まる、実際の文字列配列は0から始まるので要注意

6.コードの簡単な解説

  • まず、入力の値のパースを行う
        string input = Console.ReadLine();
        int N = int.Parse(input);
        input = Console.ReadLine();
        char[] S= input.ToCharArray();
        input = Console.ReadLine();
        int K = int.Parse(input);
  • 文字列比較で表示を分岐させる
        string ans = "";
        for(int i = 0; i < N; i++)
        {
            if (S[i] == S[K-1]) { ans += S[i]; }
            else { ans += "*"; }
        }
        Console.WriteLine(ans);

7.全コード

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        string input = Console.ReadLine();
        int N = int.Parse(input);
        input = Console.ReadLine();
        char[] S= input.ToCharArray();
        input = Console.ReadLine();
        int K = int.Parse(input);
        string ans = "";
        for(int i = 0; i < N; i++)
        {
            if (S[i] == S[K-1]) { ans += S[i]; }
            else { ans += "*"; }
        }
        Console.WriteLine(ans);
    }
}

8.最後に

久しぶりのブログ更新となってしまいました(^-^;

AtCoder Beginner Contest 124 B - Great Ocean View

冷凍食品総選挙をテレビで見て明日の晩御飯に採用しようか悩んでいる、ねむーです。

今回はAtCoder(https://atcoder.jp/contests/abc124)にて開催されました、AtCoder Beginner Contest 124 B問題「B - Great Ocean View」の問題と僕との戦闘記です。

0.はじめに

今回も、プログラミング言語C#を使用しています。

1.問題文

東西に N 個の山が連なっており、西の果てには広大な海が広がっています。

各山頂には旅館があり、あなたは海を眺められる旅館を選ぶことにしました。

西から i 番目の山の高さは H i です。

西から 1 番目の山頂にある旅館からは必ず海を眺めることができます。

西から i ( i= 2 , 3 , . . . , N ) 番目の山頂にある旅館については、 H 1 ≤ H i , H 2 ≤ H i , . . . , かつ H i − 1 ≤ H i のとき、その旅館から海を眺めることができます。

これら N 個の旅館のうち、海を眺められる旅館はいくつあるでしょうか?

2.制約

  • 入力は全て整数である。
  • 1 ≤ N ≤ 20
  • 1 ≤ H i ≤ 100

3.入力例

  • 入力
5
4 5 3 5 4
  • 出力
3

4.初見の感想

  • H iがH 1~H iまでの中で最大値であれば海が見える
  • 毎回1~iまでの高さの最大値を計算してると計算量が大変
  • 最大値を保存する変数を作ることで、今までの最大値と現在の値を比較する一回の計算で済むようになる

5.コードの簡単な解説

  • まず、入力の値のパース、ループで更新する変数の準備
        int N = int.Parse(Console.ReadLine());
        string[] input = Console.ReadLine().Split(' ');
        int max = 0;
        int count = 0;
  • ループで最大値とカウントを更新
        for(int i = 0; i < N; i++)
        {
            int high = int.Parse(input[i]);
            if (max <= high) { max = high;
                count++;
            }
        }
  • 出力
        Console.WriteLine(count);

6.全コード

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        int N = int.Parse(Console.ReadLine());
        string[] input = Console.ReadLine().Split(' ');
        int max = 0;
        int count = 0;
        for(int i = 0; i < N; i++)
        {
            int high = int.Parse(input[i]);
            if (max <= high) { max = high;
                count++;
            }
        }
        Console.WriteLine(count);
    }
}

7.最後に

このB問題は5分で解けたので成長を感じています!