昨日のABC165はA,B,Dの3完でパフォーマンス720。

レーティングは最高を更新し541になりました。

 

C問題にまったく手がでず、飛ばしてDを解いた判断がよかったです。

しかし、C問題は、解説を見て、いずれはクリアーしなければならない問題だと思いました。

C問題の解説、まだ理解できませんがこの先の目標にするラインが見えてきたような気がします。再帰を使ったDFSを自在に使いこなせるようになりたいです。

C問題をACしているのは約2500人、今回参加者の上位20%程度です。
今回ちらっと見えた頂あたりに到達すれば水色の世界が見えてくるように思います。

解説のポイントから

A:

制約を見るといずれの数も高々1000なので簡単なのは全ループをかけるのが楽。

----
#include <iostream>
using namespace std;

int main(){
  int A,B,K;
  cin>>K>>A>>B;
  for(int i=A;i<=B;i++){
    if(i%K==0){
      cout<<"OK"<<endl;
      return 0;
    }
  }
  cout<<"NG"<<endl;
  return 0;
}
----


A問題ではループかけなくても解ける問題を出している。

B以下で最大のKの倍数を求め,これがA以上かで判定。

----
#include <iostream>
using namespace std;

int main(){
  int A,B,K;
  cin>>K>>A>>B;
  if(B/K*K>=A ){
    cout<<"OK"<<endl;
    return 0;
  }
  cout<<"NG"<<endl;
  return 0;
}
----

B問題

解説では1% 1/100を加えていく処理をしていた。

私の提出コード。
これでも問題なくAC。

-------------
#include <bits/stdc++.h>
using namespace std;
 
int main(){
    long long K;
    long long n=100;
    long long ans=0;
    cin>>K;
    while(n<K){
        n*=1.01;
        ans++;
    }
   
    cout<<ans<<endl;
}
------------

C問題

制約にNとMが小さいのがポイント。
これは気づいたが全列挙するようなアルゴリズムが書けなかった。

〇と仕切り|の並べ方の問題と考える。

〇|〇〇|||〇||〇||

10までの数での数列だと仕切りは9個
19 choose 9= 92378通り
グーグル検索で電卓代わりに使える。

dfsで全探索をかけたいのでグローバルに変数宣言をおく
(行儀がよくない?)

vector を引数にdfs呼び出すとか超絶技巧。

空配列にpush_back()ができない。

再帰
 1ステップで何をすれば次につなげられるか
 終了条件は何か

この手のdfsは頻用するのですらっとかけるようになっているとよい。

----
void dfs(vector<int> A){
   if(A.size()==n+1){
     int now =0;
     rep(i,q){
       if<条件にあうもののansを加算>
     }
     ans=max(ans,now);
     return;
   }

   A.push_ack(A.back());
   while(A.back()<=m){
     dfs(A);
     A.back()++;
   }
}
----
  main関数からは

  dfs(vector<int>(1,1));
 
 で呼び出し。
 dfs(0)で呼んでいないのは空配列にpush_back()ができないから。