chacoderのブログ

競技プログラミングそのほか

ABC181参戦記

f:id:chacoder:20201102220942p:plain

はじめに

2020年11月1日21:00-22:40に開催されたABC181に出場しました。
5分42秒2完ノーペナでパフォーマンスは300,レートは41下がって736になりました。

A問題

偶奇の判定だけの簡単な問題です。
しっかりチェックして提出し1分29秒。

B問題

これも比較的簡単な問題。
連続した数字の足し算は最近よく見る気がします。
丁寧にチェックして提出し4分13秒。通算5分42秒。
ここまでは順調でした。

#include <bits/stdc++.h>
using namespace std;

long long A[100010];
long long B[100010];

int main(){
  long long N;
  cin>>N;
  long long sum=0;
  for(int i=0;i<N;i++){
    cin>>A[i]>>B[i];
    sum+=(B[i]+A[i])*(B[i]-A[i]+1)/2;
  }
  cout<<sum<<endl;
  return 0;
  
}

C問題

幾何問題で3点が同一直線上にあるかどうかの判定です。
N<=100なのでO(N^3)で間に合いますので全探索する方針で書きました。

最初の提出は0除算をしてしまっており,WAに。

X軸に平行な場合に0除算になるのを防ぐためx座標が同じものが3つあれば同一直線上と判定することにして,この部分をmapで実装しました。

方針はよかったのですが何故かTLE。

終了後に気づいたのはmapの要素数のカウントのところを書き間違えてました。
例の(for itr=mp.begin();itr !=mp.end();itr++)が書けてませんでした。
CEにならなかったので気づきませんでした。

終了後に気づいて提出しACしましたが痛恨のミスです。

D問題

C問題がなかなか解けないので30分経過ぐらいでD問題に移りました。

1000は8で割り切れるので,3ケタ以上のものについては,下3ケタが8の倍数かどうかで判定しました。

問題を読み間違えていて使う数字は1~9ですが,0~9と考えても影響はありませんでした。

だいぶ苦労して実装したけどなかなかWAになるケースが取れません。

終了後に改めてコードを見ていたらand とor を一か所書き間違えていることに気づきました。
これも単純ミスですが時間内に気づけず痛かったです。

まあ,書いたコードもぐじゃぐじゃで,もっとすっきりかければミスにも気づきやすかったと思います。

ちなみに1行が長くなるとみにくくなるので,改行してかき分けている部分がありますが時間の無駄といえば無駄でこのあたりも工夫したいです。

WAしたコードと間違っていたところ

#include <bits/stdc++.h>
using namespace std;

int main(){
  string S;
  cin>>S;
  int len=S.size();
  int temp;
  map<int,int>mp;
  for(int i=0;i<len;i++){
    temp=S.at(i)-'0';
    mp[temp]++;
  }
  if(len==1 && mp[8]==1){
    cout<<"Yes"<<endl;
    return 0;
  }
  
  if(len==2){
    if(S=="16"||S=="61"||S=="24"||S=="42"||S=="32"||S=="23"||S=="40"){
      cout<<"Yes"<<endl;
      return 0;
    }
    if(S=="48"||S=="84"||S=="56"||S=="65"||S=="64"||S=="46"||S=="72"){
      cout<<"Yes"<<endl;
      return 0;
    }
    if(S=="27"||S=="80"||S=="88"||S=="96"||S=="69"||S=="04"||S=="08"){
      cout<<"Yes"<<endl;
      return 0;
    }    
  }
  //末尾000
  if(mp[0]>2){
      cout<<"Yes"<<endl;
      return 0;
  }
  int n=104;
  int d1,d2,d3;
  while(n<=992){
    temp=n;
    d1=temp%10;
    temp/=10;
    d2=temp%10;
    temp/=10;
    d3=temp;
    //判定
    int x1=mp[d1];
    int x2=mp[d2];
    int x3=mp[d3];
    if(d1 != d2 || d1 != d3|| d2 != d3){   //ここは||ではなく&&が正しい
      if(x1>0 && x2>0 && x3>0){
        cout<<"Yes"<<endl;
        return 0;
      }
    }
    if(d1 == d2 && d2 != d3){
      if(x1>1 && x3>0){
        cout<<"Yes"<<endl;
        return 0;
      }
    }
   if(d1 == d3 && d2 != d3){
      if(x1>1 && x2>0){
        cout<<"Yes"<<endl;
        return 0;
      }
    }   
   if(d1 != d3 && d2 == d3){
      if(x1>0 && x2>1){
        cout<<"Yes"<<endl;
        return 0;
      }
    } 
    if(d1==d2 && d2==d3){
      if(x1>2){
         cout<<"Yes"<<endl;
        return 0;
      }
    }  
    n+=8;
  }
  cout<<"No"<<endl;
  return 0;
}

反省点と感想

今回のC,Dはいずれも実装力不足からくる事故でしたが,両方とも時間内に解けたとしても,冷えずに済んだかどうか微妙なところです。

4完でも1時間以内ぐらいに解けないと緑パフォがでないので厳しい世界です。
本当にみんなのレベルがあがってるなと感じます。

半年ぶりの灰パフォで4連続冷えで緑がますます遠くなりましたが,残念ながらこれが今の実力です。

少し長い目で見て,緑安定を目指して精進を重ねたいと思います。