2022牛客寒假算法基础集训营5

G

163小孩 

题意:编号1~13的牌,每种4种花色,求在不考虑花色的情况下,从中取出6张的不同方案数。

#include <bits/stdc++.h>

using namespace std;

int cnt[04];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    long long res = 0;
    
    for (int a = 0; a <= 4; a++)
        for (int b = 0; b <= 4; b++)
            for (int c = 0; c <= 4; c++)
                for (int d = 0; d <= 4; d++)
                    for (int e = 0; e <= 4; e++)
                        for (int f = 0; f <= 4; f++)
                            for (int g = 0; g <= 4; g++)
                                for (int h = 0; h <= 4; h++)
                                    for (int i = 0; i <= 4; i++)
                                        for (int j = 0; j <= 4; j++)
                                            for (int k = 0; k <= 4; k++)
                                                for (int l = 0; l <= 4; l++)
                                                    for (int m = 0; m <= 4; m++)
                                                        if (a + b + c + d + e + f + g + h + i + j + k + l + m == 6) res++;
    cout << res << "\n";
    return 0;
}

I

兔崽小孩 

2022牛客寒假算法基础集训营5

 思路:先求出不考虑入睡需要的时间下的每段休息时长存入d数组,求出最大休息时长sum,然后将每段休息时长从小到大排序,求出d数组的前缀和s[i],二分找到第一段大于k的d数组下标i,此时的休息时长=最大时长-前i-1段的时长-剩余段数*k。即ret=sum-s[i-1]-k*(n-i)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e6 + 10;
const int inf=0x3f3f3f3f;
ll n,q;
ll s[maxx];//s[i]表示前i段的休息时长
ll d[maxx];//不考虑入睡的各段休息时长
void solve()
{
    scanf("%lld %lld",&n,&q);
    ll tem;
    scanf("%lld",&tem);
    for(int i=2;i<=n;i++)
    {
        ll x;
        scanf("%lld",&x);
        d[i-1]=x-tem;
        tem=x;
    }
    sort(d+1,d+n);
    ll sum=0;
    for(int i=1;i<=n-1;i++)
    {
        s[i]=s[i-1]+d[i];//求前缀和
        sum+=d[i];//不考虑入睡的最大休息时长
    }
    while(q--)
    {
        ll k,p;
        ll ret=0;
        scanf("%lld %lld",&k,&p);
        ll i=upper_bound(d+1,d+n,k)-d;//二分找到第一段休息时长大于k的下标
        ret=sum-s[i-1]-(n-i)*k;//休息时长=最大时长-前i-1段的时长-剩余段数*k
        if(ret>=p) printf("Yes\n");
        else printf("No\n");
    }
    
}
int main()
{
    int _t=1;
    //scanf("%d", &_t);
    while (_t--)
    {
        solve();
    }
    system("pause");
}

J

三国小孩

题意:现在自己有n张杀,m张决斗,无限滴血,对手有k张牌1滴血,问是否能在一回合内击败对手。

思路:

己方每出一张牌对方也得跟一张才能免除伤害,直接判断n+m是否大于k即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    if(k < m + n) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;



    system("pause");
    return 0;
}
上一篇:前缀和(原理+应用)


下一篇:itertools 模块学习笔记