2026牛客寒假算法基础集训营6(K H G B A)

K 小L的游戏1

思路:

问最后一次操作是谁进行的,先计算一下最多能进行多少次两人操作,然后再看是增加 m 超过 z 还是增加 m+n 超过 z。
代码:

cpp 复制代码
void solve()
{
    int m,n,z;
    cin>>m>>n>>z;
    int cnt=(z-1)/(m+n);
    int ans=cnt*(m+n);
    if(ans+m>=z)cout<<"0";
    else cout<<"1";
}

H 小L的数组

思路:

一共就两种操作,按位异或是不会超过 2048 的所以开个 2048 的数组就可以。用 dp[i] 来表示这个数字能否到达,然后进行 n 步操作,每一步操作都有一个内循环去处理之前操作所能到达的值。注意不要在内循环中直接去修改 dp 数组这样会导致错误,所以先用一个 ne 数组去存储。

然后从大到小找所能到达的最大值即可。
代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
const int N=2100;
int a[N],b[N];
bool dp[2048],ne[2048];
void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    memset(dp,0,sizeof dp);
    dp[0]=1;
    for(int i=1;i<=n;i++)
    {
        memset(ne,0,sizeof ne);
        for(int x=0;x<2048;x++)
        {
            if(!dp[x])continue;
            int m=max(0LL,x-a[i]);
            ne[m]=1;
            m=x^b[i];
            ne[m]=1;
        }
        for(int j=0;j<2048;j++)
            dp[j]=ne[j];
    }
    for(int i=2047;i>=0;i--)
    {
        if(dp[i]){
            cout<<i;
            break;
        }
    }
}
signed main()
{
    int t=1;
    IOS
    while(t--)
    {
        solve();
    }
}

G 小L的散步

思路:

首先先来个起步检测,如果一开始就踩缝隙了,直接 YES,用前缀和数组+二分查找来进行之后的判断,用前缀和可以记录每个缝隙的位置,二分去找第一个大于后脚跟的缝隙,之后判断是否猜到缝隙。不要暴力,会超时。
代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
const int N=2e5+5;
int a[N],b[N],s[N];
void solve()
{
    int n,m,l;
    cin>>n>>m>>l;
    s[0]=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>b[i];
    }
    if(l>a[1])
    {
        cout<<"YES";
        return;
    }
    int last=0;
    for(int i=1;i<=m;i++)
    {
        last+=b[i];
        int le=1,r=n,j=-1;
        while(le<=r)
        {
            int mid=(le+r)/2;
            if(s[mid]>=last){
                j=mid;
                r=mid-1;
            }else{
                le=mid+1;
            }
        }
        if(j!=-1&&s[j]<last+l&&s[j]>last)
        {
            cout<<"YES";
            return;
        }
//         for(int j=1;j<=n;j++)
//         {
//             if(s[j]>last&&s[j]<last+l)
//             {
//                 cout<<"YES";
//                 return;
//             }
//         }
    }
    cout<<"NO";
}
signed main()
{
    int t=1;
    IOS
    while(t--)
    {
        solve();
    }
}

B 小L的彩球

思路:

要有 t 根线其实就是把这 n 个球分成 t+1 块,有两种情况,奇数块归左边或者是奇数块归右边。所以可以计算出左右两盒的块数,奇数块数在计算时需要上取整。然后其实就是在左边 x 个球中划分出 l 个块,就是 Cl−1x−1C^{x-1}{l-1}Cl−1x−1,右边是 Cr−1y−1C^{y-1}{r-1}Cr−1y−1。反之同理。

组合数的计算可以等之后会发一篇简单数学。
代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl "\n"
const int MOD=998244353;
const int N=1e6+5;
int fact[N],infact[N];
int qmi(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1){
            res=a*res%MOD;
        }
        b>>=1;
        a=a*a%MOD;
    }
    return res;
}
void pre()
{
    fact[0]=infact[0]=1;
    for(int i=1;i<N;i++)
    {
        fact[i]=fact[i-1]*i%MOD;
//         infact[i]=infact[i-1]*qmi(i,MOD-2)%MOD;
    }
    infact[N-1]=qmi(fact[N-1],MOD-2);
    for(int i=N-2;i>=0;i--){
        infact[i]=infact[i+1]*(i+1)%MOD;
    }
}
int C(int n,int k)
{
    if(k<0||k>n)return 0;
    return fact[n]*infact[k]%MOD*infact[n-k]%MOD;
}
void solve()
{
    int n,x,t;
    cin>>n>>x>>t;
    if(t==0){
        if(x==0||(n-x)==0){
            cout<<"1"<<endl;
        }else cout<<"0"<<endl;
        return;
    }
    int k=t+1;
    int ans=0;
    int l=(k+1)/2,r=k/2;
    if(l<=x&&r<=n-x&&l>0&&r>0){
        ans=(ans+C(x-1,l-1)*C(n-x-1,r-1)%MOD)%MOD;
    }
    if(r<=x&&l<=n-x&&l>0&&r>0){
        ans=(ans+C(x-1,r-1)*C(n-x-1,l-1)%MOD)%MOD;
    }
    cout<<ans<<endl;
}
signed main(){
	IOS
	int T;
	cin>>T;
    pre();
	//int t=1;
	while(T--)
	{
		solve();
	}
}

A 小L的三角尺

思路:

考察数学的,首先明确三角形的斜边长度是两直角边的平方和。

那么打磨后的斜边长为 (x2+(y−t)2)\sqrt{(x^2+(y-t)^2)}(x2+(y−t)2) ,对这个函数对 t 求导得 −y−t(x2+(y−t)2)-\frac{y-t}{\sqrt{(x^2+(y-t)^2)}}−(x2+(y−t)2) y−t。

可以把这个看成一个单位贡献值,也就是打磨 1 单位长度后斜边减少多少。这个值随着 t 得增加而减少。

将这个单位贡献值从大到小进行排列,每次打磨一单位后重新计算。用优先队列来存储。

然后就是简单的计算了,最后一个循环把现在的斜边长计算出来。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define x first
#define y second
#define endl "\n"
#define PII pair<double,int>
const int N=5e5+5;
int a[N],b[N];
double r[N];
double cal(int i)//用来计算单位贡献值
{
    if(r[i]<=0)return 0.0;
    else return r[i]/sqrt(1.0*a[i]*a[i]+r[i]*r[i]);
}
void solve()
{
    int n,w;
    cin>>n>>w;
    double sum=0;
    int total=0;
    int aa=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i]>>b[i];
        r[i]=b[i];
        aa+=a[i];
        total+=b[i];
        sum+=sqrt(1.0*a[i]*a[i]+1.0*b[i]*b[i]);
    }
    if(w>=total){//惊天刚试了一下这个特判可以不用
        cout<<fixed<<setprecision(9)<<aa;
        return;
    }
    priority_queue<PII> p;//大根堆所以不用greater<>
    for(int i=1;i<=n;i++)
    {
        p.push({cal(i*1LL),i});
    }
    while(w&&!p.empty())
    {
        auto [f,i]=p.top();//取出当前最高贡献的
        p.pop();
        if(f=0)break;
        if(r[i]<=0)continue;
        w--;//打磨一单位
        r[i]--;//打磨一单位
        p.push({cal(i*1LL),i});//重新计算贡献后入队
    }
    double ans=0;
    for(int i=1;i<=n;i++)
    {
        ans+=sqrt(1.0*a[i]*a[i]+r[i]*r[i]);
    }
    cout<<fixed<<setprecision(9)<<ans;
}
signed main(){
	IOS
    int t=1;
	while(t--)
	{
		solve();
	}
}

🤔为什么把上一个题代码复制后总忘记改 N,罚时比我重写一遍都长。😭😭

看了 WIDA 的验题考虑后补 DE 吧

相关推荐
啊吧啊吧abab1 小时前
二分查找与二分答案
c++·算法·二分
AC赳赳老秦1 小时前
2026 智能制造趋势:DeepSeek 助力“黑灯”工厂运营,实现生产流程自动化
网络·数据结构·算法·安全·web安全·prometheus·deepseek
程序员酥皮蛋1 小时前
hot 100 第三十题 30. 两两交换链表中的节点
数据结构·算法·leetcode·链表
寻寻觅觅☆2 小时前
东华OJ-基础题-131-8皇后·改(C++)
c++·算法·深度优先
程序员徐师兄2 小时前
基于 Python 深度学习的电影评论情感分析算法
python·深度学习·算法·电影情感分析算法·评论情感分析
ShineWinsu2 小时前
对于C++中list的详细介绍
开发语言·数据结构·c++·算法·面试·stl·list
_OP_CHEN2 小时前
【算法提高篇】(三)线段树之维护更多的信息:从基础到进阶的灵活运用
算法·蓝桥杯·线段树·c/c++·区间查询·acm/icpc·信息维护
mjhcsp2 小时前
C++Lyndon 分解超详解析
c++·算法·lyndon
Mr_health2 小时前
leetcode:组合排列系列
算法·leetcode·职场和发展