vj补题SDUT 2023 Summer Individual Contest - 5(for 22)

B - Glider

 这道题有点不明白,先放在这里以后看

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
LL dis[N], n, m, k, x, t, T, sum[N], h;
struct node
{
    LL l, r;

} f[N];
int lbound(int x)
{
    int L = x, R = n, ans = x;
    while (L <= R)
    {
        int mid = (L + R) / 2;
        if (sum[mid] - sum[x] < h)
        {
            ans = mid;
            L = mid + 1;
        }
        else
            R = mid - 1;
    }
    return ans;
}
int main()
{
    cin >> n >> h;
    for (int i = 0; i < n; i++)
    {
        cin >> f[i].l >> f[i].r;
        if (i > 0)
        {
            dis[i] = f[i].l - f[i - 1].r;
            sum[i] = sum[i - 1] + dis[i];
        }
    }
    dis[n] = h + 1;
    sum[n] = sum[n - 1] + dis[n];
    LL ans = 0, tmp;
    for (int i = 0; i < n; i++)
    {
        int pos = lbound(i);
        tmp = (h - (sum[pos] - sum[i]) + f[pos].r) - f[i].l;
        ans = max(ans, tmp);
    }
    cout << ans;
    return 0;
}



C - Bacteria

 思路:使用优先队列,取出x1、x2 如果x1==x2,就将2*x1放入优先队列中;如果不相等就将2*x1与x2放入队列,同时sum++。如果取出x1之后队列为空,说明只有一个细胞了,就可以break掉,如果sum的数量大于3e5,就可以认为没有答案输出“-1”;

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;

void ClearFloat()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
priority_queue<LL, vector<LL>, greater<LL>> q;
int main()
{
    ClearFloat();
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> x;
        q.push(x);
    }
    int sum = 0;
    int flag = 0;
    while (q.size())
    {
        LL x1 = q.top();
        q.pop();
        if (q.empty())
            break;
        LL x2 = q.top();
        q.pop();
        if (x1 == x2)
            q.push(2 * x1);
        else
        {
            sum++;
            q.push(2 * x1);
            q.push(x2);
        }
        if (sum > 3e5)
        {
            flag = 1;
            break;
        }
    }
    if (flag)
        cout << "-1";
    else
        cout << sum;
    return 0;
}

F - Tickets

思路: 预处理,先将0-1000000所有的unluckiness给算出来,然后直接输出答案即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;
int num[N];
string s;
void ClearFloat()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
int sum(int n)
{
    int sum = 0;
    while (n > 0)
    {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}
void pre()
{
    for (int i = 0; i < 1000000; i++)
    {
        int a = sum(i / 1000);
        int b = sum(i % 1000);
        k = abs(a - b);
        num[k]++;
        for (int j = 0; j < k; j++)
        {
            v[i] += num[j];
            //v[i]保存所有小于i的编号中不幸值更小的数量
        }
    }
}
int main()
{
    ClearFloat();
    pre();
    cin >> T;
    while (T--)
    {
        n = 0;
        cin >> x;
        cout << v[x] << endl;
    }
    return 0;
}

H - Theater Square

 思路:英语看不懂不要紧,根据样例二能够看出这个tiles要横着铺,不能竖着铺。我们将整体分为三个部分,没有⛲️的行(上下都可能有),⛲️左边一块,⛲️右边一块,如果是奇数,说明就需要一块1×1的瓷砖,如果是偶数就不需要,然后求出三部分需要1×1的瓷砖数量总和。判断一下,如果是偶数就打破sum/2块瓷砖,如果是奇数需要多打破一块🧱

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;

void ClearFloat()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    ClearFloat();
    int y, x1, x2, y1, y2;
    cin >> x >> y;
    cin >> x1 >> y1 >> x2 >> y2;
    int sum = 0;
    int a = 0, b = 0, c = 0;
    a = y % 2 * (x - x2 + x1 - 1);//除去喷泉剩余行数需要打破几块🧱
    b = (y1 - 1) % 2 * (x2 - x1 + 1);//喷泉左边需要打破几块🧱
    c = (y - y2) % 2 * (x2 - x1 + 1);//喷泉右面需要打破几块🧱
    // cout << a << " " << b << " " << c << endl;
    sum = a + b + c;
    if (sum % 2 == 0)
        sum /= 2;
    else
        sum = (sum + 1) / 2;
    cout << sum;
    return 0;
}

I - Heist

 

 思路:店铺拥有键盘的最小数量就是现存的最小编号到最大值编号之间的数量,最大编号➖最小编号➕1➖现存数量 就是被偷的最小数量

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
LL n, m, k, x, t, T;

void ClearFloat()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    ClearFloat();
    LL minn = 9999999999, maxx = 0, ct = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> x;
        minn = min(minn, x);
        maxx = max(maxx, x);
    }
    cout << maxx - minn + 1 - n;
    return 0;
}

J - Buying a TV Set

 思路:求给出的比例的最小整数比,然后求min(最大长度/比例长度,最大宽度/比例宽度)就是答案

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
LL v[N], n, m, k, x, t, T;

void ClearFloat()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    ClearFloat();
    LL a, b, sum = 0;
    cin >> a >> b >> n >> m;
    k = gcd(n, m);
    // cout << k << endl;
    n = n / k;
    m = m / k;
    // cout << n << " " << m << endl;
    // cout << a / n << " " << b / m << endl;
    sum = min(a / n, b / m);
    cout << sum;
    return 0;
}

 K - Medians and Partition

思路:一开始我没看到 If the array has even length let median be smallest of of two middle elements. 这句话,看题解也没看明白是什么意思。这道题中位数的定义与数学里中位数的定义不同,如果是偶数个数字,中位数取中间呢个数的小的值,例如两个数「1,7」数学中的中位数是(1+7)/2=4、而在这道题中位数应该取1.

        所以我们可以很轻易得出结论,一个小于m的数需要至少两个大于等于m的数组在一起才能使他们的中位数大于等于m,因此计算大于等于m的数的数量与小于m的数的数量差就是答案,注意如果小于m的数量更多的话答案应该是0,所以要和0取一个max.

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;

void ClearFloat()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    ClearFloat();
    int l = 0, r = 0;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> x;
        if (x >= m)
            r++;
        else
            l++;
    }
    cout << max(r - l, 0);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值