読者です 読者をやめる 読者になる 読者になる

AtCoder Regular Contest 052

4月30日に行われたARC052に参加しました。
結果はA,B問題を通しての200点で順位は158位でした。D問題で10点部分点を取れれば100位以内に入れたのでなんとかしたかったですね。やはりコード書くのが遅すぎるのが問題だと感じます。
以下各問振り返り
(今回解説放送をほとんど真面目に聞いていなかったのであまりちゃんとした反省になっていません……)

A問題『何期生?』

受け取った文字列を頭から見ていって数字があったらひとつ次まで調べればいいのだろうと考えました。この程度のプログラムにも16分かかるのが今の実力という感じです。

int main(){
    string s;
    int ans=0;
    cin>>s;
    REP(i,s.size()){
        if('1'<=s[i]&&s[i]<='9'){
            if('0'<=s[i+1]&&s[i+1]<='9'){
                ans = (s[i] - '0')*10 + s[i+1] - '0';
                break;
            }else{
                ans = s[i] - '0';
                break;
            }
        }
    }
    cout<<ans<<endl;
}

B問題『円錐』

各円錐について、{a\leq x\leq b}の領域に一部分でもあるかを判定して、あったら計算すればいいのだろうと。nが小さいからたぶんこういう愚直なやりかたでいけるんだろうなぁと思いました。
piを整数で宣言してしまったり、返り値で整数を宣言していたりで計算が合わず四苦八苦してしまいました。なにも考えずint書くのほんとダメ。ここの実装でものすごく時間使ってしまったのが反省点です(今提出時刻確認したら1時間以上も使ってしまったいた……)。
でも近くの順位の人を見るとだいたいそんな感じなのでこれはそういう問題なのでしょうね。 [a,b]内にある部分の体積計算は同じようなコード書きまくってるし、もっとうまくやれそうな気もしますが、具体的にどうというのは思い浮かびませんね。

const double pi = 3.1415926535;

class cone{
    public:
        double x,r,h;
        bool isIn(double a,double b){
            if(x<=a&&a<=x+h||a<=x&&x<=b){
                return true;
            }else{
                return false;
            }
        }
        double V(){
            return pi*r*r*h/3.0;
        }
        double Vab(double a,double b){
            if(x<=a&&x+h<=b){
                cone small;
                small.h=x+h-a;
                small.r=r*small.h/h;
                return small.V();
            }else if(x<=a&&b<x+h){
                cone small,large;
                small.h=x+h-b;
                small.r=r*small.h/h;
                large.h=x+h-a;
                large.r=r*large.h/h;
                return large.V()-small.V();
            }else if(a<=x&&b<x+h){
                cone small;
                small.h=x+h-b;
                small.r=r*small.h/h;
                return V()-small.V();
            }else{
                return V();
            }
        }
};

int main()
{
    int n,q;
    cin>>n>>q;
    vector<cone> c(n);
    double a,b;
    REP(i,n){
        cin >> c[i].x >> c[i].r >> c[i].h;
    }
    REP(i,q){
        cin>>a>>b;
        double sum=0;
        REP(j,n){
            if(c[j].isIn(a,b)){
                sum+=c[j].Vab(a,b);
            }
        }
        printf("%4f\n",sum);
    }
}

C問題『高橋くんと不思議な道』

問題文を見た瞬間、これはできないやつだと悟りました(時間も少なかったし)。ノードとエッジが出てくる経路系の問題に慣れていなさすぎてちょっと苦手意識を持っているのはよくないですね。DPも含めて意識的に訓練しないとできるようにならなさそうな分野だと思っています。

D問題『9』

問題文開いた時点で残り10分くらいしか時間がなく、部分点だけを狙いにいきましたが失敗。 以下がその時書いたコード

#include <bits/stdc++.h>
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,n) for (int i=0;i<(n);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)
using namespace std;
int main()
{
    long long int k,m;
    cin>>k>>m;
    int c=0;
    REP(i,m){
        int isum=0;
        int j=i;
        while(1){
            isum+=j%10;
            j/=10;
            if(j==0)break;
        }
        if(i%k==isum%k)c++;
    }
    printf("%d\n",c);
}

これREPで書いてしまっているので0スタートになってて間違いだったようです。(forで書いたら10点分は取れました)
マクロ使うのが悪いわけではないと思うのですが、こういうミスをしてしまうとちょっと考えてしまいますね。