C++競プロ学習日記(仮)

( 学習記録であり解説Blogではないです )

Round#91 A. Lucky Division|Codeforces

Problem - 122A - Codeforcesを解きました。

#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(n); i++)
using namespace std;
struct cww{cww(){ios::sync_with_stdio(false);cin.tie(0);}}star;
bool check( int N ){
    string S = to_string( N );
    REP( i, (int)S.size() )
    {
        if( S[i] != '4' && S[i] != '7' ) return false;
    }
    return true;
}
int main()
{
    int N{};
    cin >> N;
    cout << ( check( N ) || N % 4 == 0 || N % 7 == 0 || N % 47 == 0 || N % 74 == 0 ? "YES" : "NO" ) << endl;
    return 0;
}

lucky digits47
lucky digitsのみで構成されるNとlucky digitsで割り切れるNがlucky。

Switching Railroad Cars|AOJ|stack

stackに慣れる為に車両入れ替え | Aizu Online Judgeを解きました。

#include <bits/stdc++.h>
using namespace std;
struct cww{cww(){ios::sync_with_stdio(false);cin.tie(0);}}star;
int main()
{
    int N;
    stack<int> st;
    while( cin >> N )
    {
        if( N == 0 ){
            // 0が来たら取り出し
            cout << st.top() << endl;
            st.pop();
            continue;
        }
        // 0以外はstackに積む
        st.emplace( N );
    }
    return 0;
}

TLE本でstackを勉強してから使ってなかったので、使い方の確認をしました。
st.push(N)よりst.emplace(N)(C++11)を使うようにしています。

stackコンテナアダプタ!

参考)stack - cpprefjp C++日本語リファレンス

C++ で 桁和

#include <bits/stdc++.h>
using namespace std;
int digit( int N )
{
    while( N >= 10 )
    {
        int tmp{};
        while( N > 0 )
        {
            tmp += ( N % 10 );
            N /= 10;
        }
        N = tmp;
    }
    return N;
}
int main()
{
    int N{};
    cin >> N;
    cout << digit( N ) << endl;
    return 0;
}

とある問題で桁和を使うのかと思って書いたのですが、
結果的に桁和不要だったので、桁和コードだけ個別に残します...。

例えば、N799 の場合、 7 + 9 + 9 = 25 ➡︎ 2 + 5 = 7
1桁になるまで足していくコードです。
(もしかしたら、もっと簡潔な書き方があるかも知れないです...)

実行結果:[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

vector<pair<type, type>>の要素削除の仕方

#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(n); i++)
using namespace std;
struct cww{cww(){ios::sync_with_stdio(false);cin.tie(0);}}star;
int main()
{
    int N;
    cin >> N;
    
    vector<pair<int, string>> P;
    REP( i, N )
    {
        string S;
        cin >> S;
        P.emplace_back( i + 1, S );
    }
    REP( i, (int)P.size() )
    {
        if( P[i].first % 2 != 0 )
        {
            //要素を削除
            P.erase( P.begin() + i );
        }
        cout << P[i].first << " " << P[i].second << endl;
    }
    return 0;
}

pair要素の削除の仕方で時間を溶かしたのでメモ。
pairという事に囚われていたのですが、pairと言ってもvectorなので
削除の仕方はvectorと同じでした...(それはそう)
( P[ i ].first と P[ i ].second をそれぞれ erase すると何故か思っていた...)

上記コードの実行結果: [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

1)vector::erasevector::erase - cpprefjp C++日本語リファレンス
2)std::vectorvector - cpprefjp C++日本語リファレンス
3)std::pairpair - cpprefjp C++日本語リファレンス

No.24 数当てゲーム|yukicoder

No.24 数当てゲーム - yukicoder を解きました。

#include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(n); i++)
using namespace std;
struct cww{cww(){ios::sync_with_stdio(false);cin.tie(0);}}star;
int main()
{
    int N;
    cin >> N;
    
    vector<int> res( 10, 1 );
    REP( i, N )
    {
        vector<int> vc(N);
        REP( j, 4 )
        {
            cin >> vc[j];
        }
        
        string R;
        cin >> R;
        
        REP( j, 4 )
        {
            if( R == "YES" )
            {
                res[vc[j]] += 1;
            }
            if( R == "NO" )
            {
                res[vc[j]] = 0;
            }
        }
    }
    cout << distance( res.begin(), max_element( res.begin(), res.end() ) ) << endl;
    return 0;
}

・YESの中には必ず解となる数字が含まれている
・NOの中の数字が解になる事はあり得ない

まとめると、全てのYESの中に出現し、NOに一度も出現しない数字が解となる

実装はかなり迷走して、最終的に↑上記コードに落ち着きました(4回くらい書き直した(5提出))

最後のOUTPUTにカウント数が一番多いvectorのindex数を取得したい訳なんですが、
max_elementdistance の合わせ技で求まりました(便利!)

//MAX値を取得
auto MAX = max_element( res.begin(), res.end() );
//MAX値が先頭から何番目か取得
auto index = distance( res.begin(), MAX );
//index番号OUTPUT
cout << index << endl;
//1行で
cout << distance( res.begin(), max_element( res.begin(), res.end() ) ) << endl;

他にも find で見つけた値に対して distance してindexを取得したり、と大変便利。
STLって楽しい!