LoginSignup
0
0

More than 1 year has passed since last update.

AtCoder Beginner Contest 252

Last updated at Posted at 2022-05-22

A - ASCII code

O(1)
castの問題です。

C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repx(i,x,n) for(int i=x; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N;
    cin >> N;
    cout << (char)N << endl;
    return 0;
} 

B - Takahashi's Failure

O(N*M)
全探索で解きます。
実装問題です。
Aの要素で、最も値の大きい要素のindex(以下P)を計測します。
PがBの要素に含まれていたなら”Yes”。
PがBの要素に含まれていないなら”No”。

C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repx(i,x,n) for(int i=x; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N, K, max_num=0;
    cin >> N >> K;
    vector<int> A(N), B(K);
    for(auto &a:A){
        cin >> a;
        max_num = max(max_num, a);
    }
    for(auto &b:B) cin >> b;

    int ans=0;
    for(int i=0; i<N; i++){
        if(max_num != A[i]) continue;
        for(int j=0; j<K; j++){
            if(i == B[j]-1) ans=1;
        }
    }
    if(ans) cout << "Yes" << endl;
    else cout << "No" << endl;

    return 0;
} 

C - Slot Strategy

O(N*(10+10) + 10)
初見の問題で何をしていいか分かりませんでした。
まず制約から整理していきましょう。
2<=N<=100
S_iの文字数は10

何も浮かばない。
1で止めるとして、最も時間の短い数字の並び方は、

3
1937458062
8124690357
2315760849

1で止めるとして、最も時間の長い数字の並び方は、

3
1937458062
1824690357
1325760849

i番目の1の数が3個の時、スロットが止まる時間Tは、

漸化式
T = (3-1)*10 + i

テストデータをもう少し複雑にしましょう。

4
1937458062
1824690357
1325760849
9325760841

N行10列の文字列で、
i列目の任意の数字がk個の時、スロットが止まる時間Tは、

漸化式
K = i列目の任意の数字の個数
T = max(T, K-1)*10 + i)

このTの最小値を求めることができればいけそうです。

C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repx(i,x,n) for(int i=x; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N;
    cin >> N;
    vector<string> S(N);
    for(auto &s:S) cin >> s;
    vector<vector<int>> num_cnt(10, vector<int>(10));

    vector<int> time(10);    
    for(int i=0; i<10; i++){
        for(int j=0; j<N; j++){
            int num = S[j][i] - '0';
            num_cnt[i][num]++;
        }
        for(int k=0; k<10; k++){
            if(num_cnt[i][k]>0) time[k] = max(time[k], (num_cnt[i][k] - 1) * 10 + i);           
        }
    }

    int ans = 1e9 + 7;
    for(int i=0; i<10; i++){
        ans = min(ans, time[i]);
    }
    cout << ans << endl;

    return 0;
} 

D - Distinct Trio

O(N)
この問題も最初は何もわかりませんでした。
制約は、
1≤i<j<k≤N
Ai,Aj,Akは相異なる。

制約は、「1≤i<j<k≤N」ですが「整数の組み」なので順番は関係なさそうですね。
テストデータは、

sample1
4
3 1 4 1

ans=2

sample2
10
99999 99998 99997 99996 99995 99994 99993 99992 99991 99990

ans=120

10C3=120です。
sample2から、組み合わせに近い問題だと解ります。
1が二つあるsample1で考察します。
全ての組み合わせは、

_4C_3 = 4

から、1を2つ取り出す組み合わせを引き算します。
N個の要素(4)から、2つある1の組み合わせを引くと、

4 - {}_{2}C_2 * {}_{N-2}C_1

mapで同じ数字がいくつあるか計測して、引き算を行うと答えが出そうです。

C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repx(i,x,n) for(int i=x; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

// nCr を定義通りに求める関数
long long nCr(long long n, long long r) {
	long long nPr = 1;
	for(long long i = 0; i < r; ++i) {
		nPr *= (n - i);
	}

	long long fact_r = 1;
	for(long long i = 1; i <= r; ++i) {
		fact_r *= i;
	}

	long long ret = nPr / fact_r;
	return ret;
}

int main() {
    int N;
    cin >> N;
    vector<ll> A(N);
    for(auto &a:A) cin >> a;
    map<ll, ll> mp;
    for(auto &a:A) mp[a]++;
    ll sum = nCr(N, 3LL);
    for(auto &m:mp){
        if(m.second>1){
            sum -= nCr(m.second, 2) * nCr(N-m.second, 1);
            sum -= nCr(m.second, 3);
        }
    }
    cout << sum << endl;

    return 0;
} 

まとめ

C問題あたりから一瞬やばいと危機感を持ちました。
2問連続で、考察から答えを導くことができたのが大きいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0