Codeforces Round #746 (Div. 2)

A Gamer Hemose

题目大意

给定一个n, m和长度为n的数组,不能连续取两次相同的数,问取多少次才能使和大于等于m

主要思路

判断最大的两个数取几次能得到结果即可

AC代码

#include <bits/stdc++.h>

#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 200010, mod = 1e9+7;
int n, m, k, a[N];
int f[N];

signed main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n >> m;
        for(int i = 1; i <= n; i++)
        {
            cin >> a[i];
        }
        sort(a + 1, a + 1 + n);
        int ans = m / (a[n] + a[n - 1]) * 2;

        if(ans / 2 * (a[n] + a[n - 1]) == m) ;
        else if(ans / 2 * (a[n] + a[n - 1]) + a[n] >= m) ans++;
        else ans += 2;
        cout << ans << endl;
    }
    return 0;
}

B Hemose Shopping

题目大意

给定一个长度为n的数组和一个数x,我们只能交换距离大于等于x的两个数,问能否让数组变成非递减数组

主要思路

  • 当x小于等于n/2时,我们一定能得到非递减数组
  • 当x大于n/2时,在数组中间的几个数无法被交换,其余数可以任意交换,所以考虑中间无法被交换的几个数是否与排序后的数组相同即可

AC代码

#include <bits/stdc++.h>

#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 200010, mod = 1e9+7;
int n, x, a[N], b[N];

signed main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n >> x;
        for(int i = 0; i < n; i++) cin >> a[i], b[i] = a[i];
        if(x <= n / 2) cout << "YES" << endl;
        else
        {
            bool flag = true;
            sort(a, a + n);
            
            for(int i = n - x; i < x; i++)
            {
                if(a[i] != b[i]) flag = false;
            }
            
            if(flag) cout << "YES" << endl;
            else cout << "NO" << endl;
        }
    }
    return 0;
}

C Bakry and Partitioning

题目大意

给定一棵树,每个点上有权值,问能否通过减少1~k-1条边让每棵树的权值^值相同

主要思路

由于是一棵树,我们可以以任意点作为根节点,假设1号点为根,那么整棵树就能确定

  • 如果减边之前整棵树的异或值为0,那么一定可以通过减掉任意一条边让两棵树的异或值相同
  • 如果整棵树的异或值不为0,那么k == 2时一定不能通过减1条边让两棵树异或值相同
  • 我们从1号点dfs整棵树,每个点表示以这个点为根的数的异或和,如果有树与根节点的异或值相同,那么数量+1,假设数量 >= 2我们就可以从中任选两棵树将其从树上拆分下来成为单独的树,这样三棵树的异或值一定相同

AC代码

#include <bits/stdc++.h>

#define int long long
using namespace std;
#define debug(a) cout << #a << " = " << a << endl;
#define x first
#define y second
typedef long long ll;
const int N = 100010, mod = 1e9+7;
int n, k;
int h[N], e[N * 2], ne[N * 2], idx;
int a[N];

int cnt, res;

// 添加一条边a->b
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

int dfs(int root, int father)
{
    int sum = a[root];
    for(int i = h[root]; ~i; i = ne[i])
    {
        int j = e[i];
        if(j == father) continue;
        sum ^= dfs(j, root);
    }
    if(sum == res) cnt++, sum = 0;
    return sum;
}

signed main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    int T;
    cin >> T;
    while(T--)
    {
        idx = 0;
        cin >> n >> k;
        
        res = 0;
        for(int i = 1; i <= n; i++) cin >> a[i], res ^= a[i], h[i] = -1;
            
        for(int i = 0; i < n - 1; i++)
        {
            int a, b;
            cin >> a >> b;
            add(a, b);
            add(b, a);
        }
        
        cnt = 0;
        dfs(1, 0);
        
        if(res == 0) cout << "YES" << endl;
        else if(k == 2) cout << "NO" << endl;
        else if(cnt < 2) cout << "NO" << endl;
        else cout << "YES" << endl;
    }
    return 0;
}
上一篇:Codeforces Round #746 (Div. 2)


下一篇:【DB笔试面试746】在O中,“...SWITCH LOGFILE”与“... ARCHIVE LOG CURRENT”区别