Codeforces Round 902 (Div. 2, based on COMPFEST 15 - Final Round) A~D

A. Goals of Victory

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
    int n;
    cin >> n;
    int sum = 0;
    for (int i = 0; i < n - 1; i++)
    {
        int x;
        cin >> x;
        sum += x;
    }
    cout << sum * (-1) << "\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

B. Helmets in Night Light

贪心

/*
根据题意我们至少要通知给一个人,如果有人通知给别人的花费小于自己通知的花费,就让他去通知其他人。

如果没有花费小于自己通知的就都自己去通知。
需要注意的是:注意数据范围,n和p,a[i]都是10^5可能会报int,运算时记得强制转换或者初始化为long long
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
struct node
{
    int pnum;
    int cost;
};
bool cmp(struct node a, struct node b)
{
    return a.cost < b.cost;
}
void solve()
{
    int n, p;
    cin >> n >> p;
    vector<node> a(n);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].pnum;
    }
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].cost;
    }
    sort(a.begin(), a.end(), cmp);
    ll sumcost = p;
    int sumnum = 1;
    for (int i = 0; i < n; i++)
    {
        if (a[i].cost < p)
        {
            sumnum += a[i].pnum;
            if (sumnum < n)
            {
                sumcost += 1LL * a[i].cost * a[i].pnum;
            }
            else if (sumnum == n)
            {
                sumcost += 1LL * a[i].cost * a[i].pnum;
                break;
            }
            else
            {
                sumcost += 1LL * (n - sumnum + a[i].pnum) * a[i].cost;
                sumnum = n;
            }
        }
        else
        {
            break;
        }
    }
    if (sumnum < n)
    {
        sumcost = sumcost + 1LL * (n - sumnum) * p;
    }
    cout << sumcost << "\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Joyboard

打表找规律

// /*
// 打表找出规律:
// 只有k=1,2,3时才符合条件
// 当k==1时,只有当m==0时满足
// k==2时,只有当m<n或者n%m==0时满足条件
// k==3时,只有m>n且m%n!=0时满足条件
// 给出部分打表结果:
// YES 5 0 1
// YES 5 1 2
// YES 5 2 2
// YES 5 3 2
// YES 5 4 2
// YES 5 5 2
// YES 5 6 3
// YES 5 7 3
// YES 5 8 3
// YES 5 9 3
// YES 5 10 2
// YES 5 11 3
// YES 5 12 3
// YES 5 13 3
// YES 5 14 3
// YES 5 15 2
// YES 5 16 3
// YES 5 17 3
// YES 5 18 3
// YES 5 19 3
// YES 5 20 2
// YES 6 0 1
// YES 6 1 2
// YES 6 2 2
// YES 6 3 2
// YES 6 4 2
// YES 6 5 2
// YES 6 6 2
// YES 6 7 3
// YES 6 8 3
// YES 6 9 3
// YES 6 10 3
// YES 6 11 3
// YES 6 12 2
// YES 6 13 3
// YES 6 14 3
// YES 6 15 3
// YES 6 16 3
// YES 6 17 3
// YES 6 18 2
// YES 6 19 3
// YES 6 20 3
// */

//打表程序如下
// #include <bits/stdc++.h>
// using namespace std;
// typedef long long ll;
// #define has1 __builtin_popcount
// const int N = 1e6;
// // int a[N];
// ll n, m, k;
// void test(ll n, ll m, ll k)
// {
//     vector<int> a(n + 2);
//     a[n + 1] = m;
//     set<int> st;
//     st.insert(a[n + 1]);
//     for (int i = n; i >= 1; i--)
//     {
//         a[i] = a[i + 1] % i;
//         st.insert(a[i]);
//     }
//     if (st.size() == k)
//     {
//         cout << "YES " << n << " " << m << " " << k << "\n";
//     }
// }
// void solve()
// {
//     //
//     for (int i = 1; i <= 20; i++)
//     {                                 // n
//         for (int j = 0; j <= 20; j++) // m
//             for (int k = 0; k <= 20; k++)
//             {
//                 test(i, j, k);
//             }
//     }
// }
// int main()
// {
//     ios::sync_with_stdio(false);
//     cin.tie(0);
//     cout.tie(0);
//     int t;
//     // cin >> t;
//     t = 1;
//     while (t--)
//     {
//         solve();
//     }
//     return 0;
// }
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
    ll n, m, k;
    cin >> n >> m >> k;
    if (k == 1)
    {
        cout << 1 << "\n"; // 只有0一种
        return;
    }
    if (k > 3)
    {
        cout << 0 << endl;
        return;
    }
    if (m <= n)
    {
        if (k == 2)
        {
            cout << m << endl; // 除去0
            return;
        }
        else
        {
            cout << 0 << endl;
            return;
        }
    }
    else
    {
        ll sum = n - 1;
        sum += m / n;
        if (k == 2)
        {
            cout << sum << '\n';
        }
        else
        {
            cout << m - sum << '\n';
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

D. Effects of Anti Pimples

/*
通过数据分析:
随便造一组数据:
下标 : 1 2 3 4 5 6 7 8 9 10
数组a: 1 5 9 8 3 7 9 6 4 3
maxn :9 8 9 8 3 7 9 6 4 3
首先考虑一下所有的方法:就是2^n-1,在至少选一个的基础上,每个索引都有选或不选两种选择,假如选上这个索引x,就一定至少会得到maxn[x]的分数
那么我们在考虑不影响得分的基础上,添加一些无关的索引,是不是也是一种获取maxn[x]值的方法
对于选中索引x=1时,所有数都是他的倍数,都会变成绿色,最大值一定为序列为序列最大值,后面添加那个索引都一样,组合数为2^(n-1)次方,其余的n-1个数选或不选
对于索引x=2,若要满足得到的最大值仅仅只是maxn[x]=8,那么就不能选maxn[y]>8的下标y对吗?
对于索引x=3,maxn[x]=9是最大的,所以它的索引可以任意组合和添加,但是要考虑到重复的组合情况,在选中索引1时,也是任意选中2^(n-1)次方,那么这里就一定不能选1啊,所以是2^(n-2)次方
.
.
.
得出规律,按照maxn排序,一个索引x对应的maxn[x],可以随意组合后面的索引(假如从大到小排序),方法数为2^(n-x),并且不会重复,然后求得权值和即可
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
const ll MOD = 998244353;
long long qpow(long long a, long long b, long long m)
{
    a %= m;
    long long res = 1;
    while (b > 0)
    {
        if (b & 1)
        {
            res = res * a % m;
        }
        a = a * a % m;
        b >>= 1;
    }
    return res % m;
}
void solve()
{
    int n;
    cin >> n;
    vector<int> a(n), maxn(n, 0);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j <= n; j += i + 1) // 变到i从1开始,防止i=0时出现死循环
        {
            maxn[i] = max(maxn[i], a[j - 1]) % MOD; // 表示以i为索引的位置,以及i的倍数索引位置的最大值
        }
    }
    sort(maxn.begin(), maxn.end());
    ll ans = 0;
    //
    for (int i = 0, j = 0; i < n; i++, j++)
    {
        ans = (ans + maxn[i] % MOD * qpow(2LL, (ll)j, MOD)) % MOD;
    }
    cout << ans << "\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    // cin >> t;
    t = 1;
    while (t--)
    {
        solve();
    }
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值