AtCoder Beginner Contest 313

A - To Be Saikyo

#include <bits/stdc++.h>

using namespace std;


int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int n;
	cin >> n;
	vector<int> a(n);
	for( auto & i : a ) cin >> i;
	cout << max( 0 , *max_element( a.begin()+1 , a.end() ) + 1 - a.front() )<< "\n";
	return 0; 
}

B - Who is Saikyo?

#include <bits/stdc++.h>

using namespace std;


int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int n , m;
	cin >> n >> m;
	vector<int> f( n+1 , 1 );
	for( int x , y ; m ; m -- )
		cin >> x >> y ,f[y] = 0;
	int res = -2;
	for( int i = 1 ; i <= n ; i ++ ){
		if( f[i] == 1 ){
			if( res == -2 ) res = i;
			else res = -1;
		}
	}
	if( res == -2 ) res = -1;
	cout << res << "\n";
	return 0;
}

C - Approximate Equalization 2

先把期望的序列求出来,然后两个序列分别排序作差即可

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int n;
	cin >> n;
	int cnt = 0;
	vector<int> a(n);
	for( auto & i : a ) cin >> i , cnt += i;
	sort( a.begin() , a.end() );
	vector<int> b(n , cnt / n );
	cnt = cnt % n;
	for( int i = 0 ; i < cnt ; i ++ ) b[i] ++;
	reverse( b.begin() , b.end() );
	int res = 0;
	for( int i = 0 ; i < n ; i ++ )
		if( a[i] > b[i] ) res += a[i] - b[i];
	cout << res << "\n";
	return 0;
}

D - Odd or Even

这里回答的是子序列的奇偶性实际上就是异或和。

如果两个子序列的只有一个数不同,那么两个子序列异或和的异或等价这两个不同的数的异或。

所以我们可以推出\([2,k]\)中每个数的与\(1\)的异或,在结合\([1,k]\)的异或和就能推出\([1,k]\)的值。

然后再计算\(i\)\(i+k\)的异或,进而推出整个序列。

当然询问的方法有很多。

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int mod = 998244353;

int32_t main() {
    int n, k;
    cin >> n >> k;

    auto q = [](int l, int r, int x) {
        vector<int> v;
        for (int i = l; i <= r; i++)
            if (i != x) v.push_back(i);
        return v;
    };

    auto query = [](const vector<int> &v) {
        cout << "?";
        for (auto i: v)
            cout << " " << i;
        cout << endl << flush;
    };


    map<vector<int>, int> mp;
    for (int i = 1, t; i <= k; i++) {
        auto v = q(1, k + 1, i);
        query(v);
        cin >> t;
        mp[v] = t;
    }
    for (int i = 1, t; i <= n - k + 1; i++) {
        auto v = q(i, i + k - 1, 0);
        if (mp.count(v) > 0) continue;
        query(v);
        cin >> t;
        mp[v] = t;
    }

    int T1 = mp[q(1, k + 1, 1)];
    int cnt = 1;
    for (int i = 2; i <= k; i++)
        cnt += (T1 == mp[q(1, k + 1, i)]);

    vector<int> a(n + 1);
    a[1] = (mp[q(1, k, 0)] == (cnt & 1));

    for (int i = 2; i <= k; i++) {
        if (T1 == mp[q(1, k + 1, i)]) a[i] = a[1];
        else a[i] = !a[1];
    }
    for (int i = 1; i <= n - k; i++) {
        if (mp[q(i, i + k - 1, 0)] == mp[q(i + 1, i + k, 0)]) a[i+k] = a[i];
        else a[i+k] = !a[i];
    }
    cout << "!";
    for( int i = 1 ; i <= n ; i ++ )
        cout << " " << a[i];
    cout << endl << flush;
    return 0;

}

E - Duplicate

先考虑\(-1\)的情况,如果任意两个相邻的数都不为 1 那么这个地方就可以无限延长,答案就是\(-1\)

然后我们考虑倒序统计答案\(res\),对于当前的字符他每次被复制了\(s[i+1]-1\)个,一共复制了\(res\)次加上原本的\(1\)个,所以我们需要\(res\times(s[i+1]-1)+1\)次才可以把他完全删除掉。为什么是这个式子?因为能够被复制的数字只有\(1\)所以被复制的数字不会自己复制自己。

要注意的是,最后一个数字不需要删除,所以最后的答案还要减 1

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int mod = 998244353;

int32_t main(){
    ios::sync_with_stdio(0),cin.tie(0);
    int n;
    string s;
    cin >> n >> s;
    for( int i = 1 ; i < n ; i ++ )
        if( s[i] != '1' && s[i-1] != '1' )
            cout << -1 , exit(0);

    int res = 1;
    for( int i = n-2 ; i >= 0 ; i -- ){
        res = ( res + 1 + res * ( s[i+1] - '1' ) % mod ) % mod;
    }
    cout << res - 1 << "\n";
    return 0;
}
posted @ 2023-08-07 10:20  PHarr  阅读(13)  评论(0编辑  收藏  举报