C. Serval and The Formula

题目:

思路:

切勿复杂化,这只是个C!

 首先我们要知道一个性质,即 a + b = a ^ b + 2 * (a & b)

观察题目,即 x+k = a,y+k = b,a & b = 0

那问题就转化为了 (x+k) & (y+k) = 0,即使得x+k后和y+k后的二进制位没有任何一位同时为1,那我们一个显然容易想到的做法是遍历每一位,如果此时相等,那么就从此位往后找,一直找到第一个两者二进制位不相同的地方,然后加上2的i次方

但是显然,这种做法有点复杂,如果有多位连续1呢,如果后面没有呢相同位呢?

好像太复杂了,观察一下k的范围,足足有1e18,那我们是否可以加上一个很大的数,使得没有一位是相同的呢?显然是可以的,比如以下例子

x = 101010111110000101

y = 100000010101011111

我们只要让 x 加上 一个数,使得其最后变成 100000....000的形式,那么后面的数无论是什么都不影响,同时可以知道,由于 x > y,那么y加上这个数后肯定是01......的形式,即第一位是0,此时我们就可以不管y后是什么东西了,因为

这个值我们要大于1e9,所以这里我们可以选 1 << 32

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"

void solve()
{
    int x, y;
    cin >> x >> y;
    if (x == y)
    {
        cout << "-1\n";
        return;
    }
    cout << (1LL << 32) - max(x, y) << endl;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

D. Serval and Kaitenzushi Buffet

题目:

思路:

万恶的贪心

 首先我们要知道最优情况下我们要怎么选,比如对于k=2时,我们举个例子

x x x x x x x x x x 这些数是什么无所谓

我们可以先看看最多能选多少个,显然我们最多能像下面这样选

x o x x o x x o x x

也就是说我们最多能选3个且必须选3个,那么这三个怎么选呢?

对于第一个选择,我们可以在1~2之间选,对于第二个我们可以在1~5之间选,对于第三个我们可以在1~8之间选,为什么可以这样选呢?因为我们选了一个之后我们必须要空出k个位置用来吃,我们从后往前考虑,最后一个寿司可以在1~8之间选,因为最后肯定能空出两个位置让我们吃,而第二个寿司首先肯定是要在1~5之间选,因为如果我们在后面选一个,那么就必须要多空出两个位置,也就是说起码要空出4个位置,以此类推

或者这样说,上诉的o位置是我们能选的最晚的位置,所以我们要不就在o前选一个,要不就选o

总结一下规律就是遇到 (n-i) % (k+1) == 0 的位置时,我们就必须从前选一个最大的

为什么不能一次性选3个最大的呢?很显然,如果我们这样选的话会遇到这样的情况

x x x x x o o o x x,此时肯定是不可以的,这也是为什么我们要规定每个数的选择范围

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"

void solve()
{
    int n, k;
    cin >> n >> k;
    vector<int> a(n);
    int sumval = 0;
    priority_queue<int> pq;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
        pq.push(a[i]);
        if ((n - i) % (k+1) == 0)
        {
            sumval += pq.top();
            pq.pop();
        }
    }
    cout << sumval << endl;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

Logo

集算法之大成!助力oier实现梦想!

更多推荐