AtCoder Beginner Contest 002(ABC002) 解説

ABC

注意ですが、この頃のAtcoderは手探り感が強く、今の問題の傾向と大きく離れています。

AtCoder Problems

ABC埋めをするなら、Atcoder Problemで難易度表示が円グラフになっているABC042辺りから埋めるといいと思います。(なんなら最新から埋めた方がいいです)
私はブログネタのため埋めます。

ぬるから
ぬるから

1日1記事書きたいので、この辺りのコンテストは早解き出来て優秀だったりします。ただ、ためにはならない!!時間の無駄!!

A – 正直者

A - 正直者
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.

2つの入力値の大きいほうを出力する問題。
C++ならmax関数があるので、それを使いましょう。

#include<bits/stdc++.h>

using namespace std;

int main(){
    int X,Y;
    cin>>X>>Y;
    cout<<max(X,Y)<<endl;
}

没解答

RAKUという言語で提出しようとしましたが、どうやってもMLEするので没にしました。
言語使用的に、何もしなくてもメモリを大幅に消費するっぽい?
コードは合っているはずなので供養として貼っておきます。

my $A = get;
my @Aa=split(" ", $A);
if @Aa[0] > @Aa[1] {
  say @Aa[0]
} else {
  say @Aa[1]
}

COBOL解答

まず、コードを貼ります。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ATCODER.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  indata PIC X(100).
       01  a1 PIC Z(12).
       01  a2 PIC Z(12).
       PROCEDURE DIVISION.
        ACCEPT indata.
        
        UNSTRING indata DELIMITED BY SPACE INTO a1 a2.

        if a1 > a2 then
	     DISPLAY FUNCTION TRIM(a1)
        else
             DISPLAY FUNCTION TRIM(a2)
        end-if
       STOP RUN.

他人のコードを見て何となく理解できたのでCOBOLのコードの意味を記載しておきます。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ATCODER.
       DATA DIVISION.
       WORKING-STORAGE SECTION.

所謂、魔法の言葉です。これを入れておきましょう。

       01  indata PIC X(100).
       01  a1 PIC Z(12).
       01  a2 PIC Z(12).

変数宣言です。PIC後が型や出力形式になります。

        PROCEDURE DIVISION.
        ACCEPT indata.
        
        UNSTRING indata DELIMITED BY SPACE INTO a1 a2.

PROCEDURE DIVISION.は魔法の言葉です。
ACCEPT indata.で入力で、UNSTRING indata DELIMITED BY SPACE INTO a1 a2.でsplitしているっぽい?
とりあえず、この2つを書けば空白区切りの入力は受けられるみたいです。

        if a1 > a2 then
	     DISPLAY FUNCTION TRIM(a1)
        else
             DISPLAY FUNCTION TRIM(a2)
        end-if

if ~ else ~ end-ifで、これは普通の書き方ですね。
DISPLAYは出力、FUNCTION TRIMはtrim関数ですね。Z(12)は12桁に満たないときに空白埋めするので、それをtrimで削っています。

STOP RUN.

魔法の言葉。恐らく、終了の合図。

COBOL – Free (OpenCOBOL 1.1.0)
COBOL – Fixed (OpenCOBOL 1.1.0)
の2つで初ACを獲得することができました。
(本当はRAKUでやりたかった…)

B – 罠

B - 罠
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.

入力された文字から’a’,’i’,’u’,’e’,’o’を削除して出力する問題。
C++の文字削除はやや面倒なので、for文で先頭から1文字ずつ見ていきaiueoは除外するようにしました。

#include<bits/stdc++.h>

using namespace std;

int main(){
    string S;
    cin>>S;
    for(int i=0;i<S.size();i++){
        if(S[i]!='a' && S[i]!='i' && S[i]!='u' && S[i]!='e' && S[i]!='o'){
            cout<<S[i];
        }
    }
    cout<<endl;
}

※A問で無駄にRAKUやCOBOLやったせいで疲れました。

C – 直訴

C - 直訴
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.

3点が与えられるので、それらを結ぶ三角形の面積を求めよ。

ヒント
3 点 (0,0), (a,b), (c,d) で構成される三角形の面積は、|ad−bc|/2 となります。

と出てるので、これを使えばよいです。
具体的には、A,B,Cのどれかを原点に移動させ、移動させた分残りの2点も移動させ、移動後の点の位置でヒントの公式を使えばOKです。

#include<bits/stdc++.h>

using namespace std;

int main(){
    //heron
    double xa,ya,xb,yb,xc,yc;
    cin>>xa>>ya>>xb>>yb>>xc>>yc;
    xb-=xa;
    xc-=xa;
    yb-=ya;
    yc-=ya;
    double ad=xb*yc;
    double bc=yb*xc;
    double S=abs(ad-bc)/2;

    printf("%.10f\n",S);
}

D – 派閥

D - 派閥
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.

互いに知り合いである議員を集めた際に、最大何人集めれるか求める問題。
パット見、UnionFindっぽいですが多分上手くできません。(全員が全員の知り合いである必要があるため)
N<=12と制約が弱いので全探索で何とかなりそうです。

具体的にはbit全探索でN^2通り調べ、全員が全員知り合いであるパターンの人数の最大を答えとすればOKです。

#include<bits/stdc++.h>

using namespace std;

int main(){
    int N,M;
    cin>>N>>M;
    int xy[13][13]={{0}};

    for(int i=0;i<M;i++){
        int x,y;
        cin>>x>>y;
        xy[x][y]=1;
        xy[y][x]=1;
    }

    int ans=1;
    for(int i=1;i<(2<<N);i++){
        vector<int> kan;
        int n=i;
        for(int j=0;j<N;j++){
            if(n%2==1) kan.push_back(j+1);
            n/=2;
        }
        bool f=true;
        for(int j=0;j<kan.size();j++){
            for(int k=0;k<kan.size();k++){
                if(j==k) continue;
                if(xy[kan[j]][kan[k]]==0) f=false;
            }
        }
        if(f){
            ans=max(ans,(int)kan.size());
        }
    }
    cout<<ans<<endl;
}

知らない言語で解く方法

今回、RAKUもCOBOLも始めて書きましたが、ACできるコード(RAKUはMLEになるので怪しい)を書きました。
知らない言語でもACまで持っていく方法を書いておきます。(基本、どの言語にも使えますが、他人のコードを解読する必要があるため、難読言語だと厳しいです。)

AtCoder Problems

atcoder problemsにいきます。
Ranking→Language ownersにいきます。
ここで提出したい言語で検索し、1stを取っている人の名前をコピーします。

トップページに戻り、USER_IDに1stの名前を入れ
User→Submissionにいきます。
Languageを提出したい言語に設定し、提出コードを眺めます。
このとき、入力の形式等が似ている問題を選んだ方が楽です。

あとは、幾つかの提出コードを見て解読しながら問題を解けばOKです。
RAKUとCOBOLのコードはそうやって書きました。

おわりに

Atcoderの対応言語がかなり多いので、こういった遊びもできますが、たまにやると楽しいです。
COBOLコンテストとか、言語縛りコンテストやりたいですよね。難読言語で縛るとカオスになりそう…。

コメント

タイトルとURLをコピーしました