牛客小白月赛26 (A 二分 B 水 C 偏序问题 D 思维 E bfs F 区间因子之和奇偶 G 几何 H 思维 I 水 J 水)

算法竞赛题解精粹

题目链接

A-牛牛爱学习

做法:二分天数mid,最大的mid分发给mid天,剩余的尽量插在mid天,判断是否能达到m即可。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
 
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
const int N=1e6+10;
ll sum[N],a[N],m;
int n;
bool cmp(ll x,ll y)
{
    return x>y;
}
int run(int mid)
{
    ll s=0;
 
    for(int k=0;mid*k+1<=n;++k){
        for(int j=1,i=mid*k+1;j<=mid;++j,++i){
            if(a[i]-k>0) s+=a[i]-k;
        }
    }
    //if(mid==1) printf(":%lld\n",s);
    return s>=m;
}
int main()
{
    n=read(),m=read();
    rep(i,1,n) a[i]=read();
    sort(a+1,a+1+n,cmp);
 
    int l=1,r=n;
    int ans=1e9;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(run(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    if(ans==1e9) ans=-1;
 
    printf("%d\n",ans);
}

B-牛牛爱数学

做法:求根公式简单化简下,答案就是b*c/a 判断是否能整除即可。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
 
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
int main()
{
    int _=read();while(_--)
    {
        ll a=read(),b=read(),c=read();
        ll fz=b*c;
        if(fz%a==0) printf("%lld\n",fz/a);
        else puts("-1");
    }
}

C-牛牛种花

做法:偏序的经典问题。对一维排序,另一维 用线段树或者树状数组维护前缀和即可。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
 
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
const int N=2e5+10;
struct node
{
    int x,y,ty,id;
}a[N];
int X[N],Y[N],lx,ly,len,ans[N],sum[4*N];
bool cmp(node a,node b)
{
    if(a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
int qu(int id,int l,int r,int ql,int qr)
{
    if(ql<=l&&r<=qr) return sum[id];
    int mid=l+r>>1;
    int ans=0;
    if(ql<=mid) ans+=qu(id<<1,l,mid,ql,qr);
    if(qr>mid) ans+=qu(id<<1|1,mid+1,r,ql,qr);
    return ans;
 
}
void up(int id,int l,int r,int pos)
{
    sum[id]++;
    if(l==r) return ;
    int mid=l+r>>1;
    if(pos<=mid) up(id<<1,l,mid,pos);
    else up(id<<1|1,mid+1,r,pos);
}
int main()
{
    int n=read(),m=read();
    rep(i,1,n)
    {
        int x=read(),y=read();
        X[++lx]=x;
        Y[++ly]=y;
        a[++len]={x,y,1};
    }
    rep(i,1,m)
    {
        int x=read(),y=read();
        X[++lx]=x;
        Y[++ly]=y;
        a[++len]={x,y,0,i};
    }
    sort(X+1,X+1+lx);
    sort(Y+1,Y+1+ly);
    lx=unique(X+1,X+1+lx)-X-1;
    ly=unique(Y+1,Y+1+ly)-Y-1;
    //printf("lx:%d ly:%d\n",lx,ly);
 
 
    rep(i,1,len){
        a[i].x=lower_bound(X+1,X+1+lx,a[i].x)-X;
        a[i].y=lower_bound(Y+1,Y+1+ly,a[i].y)-Y;
    }
 
    //puts("***");
 
    sort(a+1,a+1+len,cmp);
    //rep(i,1,len)
    rep(i,1,len)
    {
        //printf("i:%d\n",i);
 
        if(a[i].ty==0){
            ans[a[i].id]=qu(1,1,ly,1,a[i].y);
        }
        else{
            up(1,1,ly,a[i].y);
        }
    }
    rep(i,1,m) printf("%d\n",ans[i]);
 
}

D-失忆药水

做法: 其实很简单的一道题,二分图是不含奇环的图,所以就是完全图的边数减去 最佳二分图的边数即可。

二分图边数怎么算?一边是n/2 另一边是n-n/2  两边点数相乘即可。

#include<bits/stdc++.h>
using namespace std; 
const int N=1e6+10,M=2e7+10,mod=998244353;
int n,m;
long long  dp[N];
int main()
{
    dp[2]=1;
    for(int i=3;i<N;i++)dp[i]=dp[i-1]+(i)/2;
    while(~scanf("%d",&n)){
        printf("%lld\n",1ll*n*(n-1)/2-dp[n]);
    }
    return 0;
}

E-牛牛走迷宫

做法:简单的输出路径的bfs

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
 
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
const int N=5e2+10,inf=0x3f3f3f3f;
char s[N][N];
int n,m,dir[4][2]={1,0,0,-1,0,1,-1,0};
int vs[N][N];
pair<int,int> ans[N][N];
void bfs()
{
    memset(vs,inf,sizeof(vs));
    queue<pair<int,int> >que;
    que.push({1,1});
    vs[1][1]=0;
 
    while(que.size()){
        auto now=que.front();que.pop();
 
        for(int i=0;i<4;++i){
            int x=now.first+dir[i][0];
            int y=now.second+dir[i][1];
            if(x<1||y<1||x>n||y>m||s[x][y]=='1') continue;
 
            if(vs[x][y]<=vs[now.first][now.second]+1) continue;
            //printf("x:%d y:%d\n",x,y);
            ans[x][y]={now.first,now.second};
            //printf("x:%d y:%d fi:%d se:%d\n",x,y,ans[x][y].first,ans[x][y].second);
 
            vs[x][y]=vs[now.first][now.second]+1;
            que.push({x,y});
        }
    }
}
int main()
{
    n=read(),m=read();
    rep(i,1,n) scanf("%s",s[i]+1);
    bfs();
    if(vs[n][m]==inf)
        puts("-1");
 
    else{
        int x=n,y=m;
        stack<char>sta;
        while(x!=1||y!=1){
            int nx=ans[x][y].first;
            int ny=ans[x][y].second;
            if(x==nx+1) sta.push('D');
            if(y==ny+1) sta.push('R');
            if(y==ny-1) sta.push('L');
            if(x==nx-1) sta.push('U');
 
            x=nx,y=ny;
        }
 
        printf("%d\n",sta.size());
        while(sta.size()){
            printf("%c",sta.top());sta.pop();
        }
        //sta.push(s[1][1]);
    }
}

F-牛牛的序列

做法:不太会,看的官方题解:

最后答案就是求区间的奇数平方数及其二次幂的个数。

[1,n] 的区间平方数个数  

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1000000000;
const double pi=acos(-1);

ll num(ll x)
{
    ll l=0,r=x,ans;
    while(l<=r)
    {
        ll p=(l+r)/2;
        if(p*p<=x)l=p+1,ans=p;
        else r=p-1;
    }
    return l;
}


int main()
{
    //for(int i=1;i<=1000;i++)printf("i=%d %d\n",i,sum(i));
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        if(a>b)swap(a,b);
        ll ans=num(b)-num(a-1)+num(b/2)-num((a+1)/2-1);
        //printf("ans=%lld\n",ans);
        printf("%lld\n",ans%2);
    }
    return 0;
}

G-牛牛爱几何

做法:简单几何题

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const double pi=acos(-1);
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
int main()
{
    double n;
    while(cin>>n)
    {
        double r=n/2;
        double ans=pi*r*r/4-r*r/2;
        ans*=8;
        printf("%.6f\n",ans);
    }
}

H-保卫家园

做法:很思维的一道题,智商题,做法参考官解:

不用管 每时每刻必须达到最大编制,都是忽悠人的,只需要考虑最多能有多少区间能加入即可,那当能加入区间大于k时,就删掉区间最长的那个最长的那个就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
vector<int>G[N];
int n,k;
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i){
        int l,r;
        scanf("%d%d",&l,&r);
        G[l].push_back(r);
    }
    multiset<int>st;
    int ans=0;
    for(int i=1;i<=1000000;++i){
        while(st.size()&&*(st.begin())<i) st.erase(st.begin());
        for(int v:G[i]){
            if(st.size()<k) st.insert(v);
            else{
                st.insert(v);
                st.erase(--st.end());
                ans++;
            }
        }
    }
    printf("%d\n",ans);
}

 

 

I-恶魔果实

做法:建有向图,然后求每个数值的能到达数的个数,组合数乘起来就是答案了。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
 
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
const int mod=1e4+7;
int x,n,vis[12],vs[12][12],dp[12];
 
vector<int>G[12];
 
int run(int u)
{
    if(dp[u]!=0) return dp[u];
 
    memset(vis,0,sizeof(vis));
    int ans=0;
    queue<int>que;que.push(u);
 
    while(que.size()){
        int now=que.front();que.pop();
        ans++;vis[now]=1;
        for(int v:G[now]) if(!vis[v]) {
            que.push(v);
            vis[v]=1;
        }
    }
    dp[u]=ans;
    return ans;
}
int main()
{
    x=read(),n=read();
    rep(i,1,n)
    {
        int u=read(),v=read();
        if(vs[u][v]) continue;
        vs[u][v]=1;
        G[u].push_back(v);
    }
 
    int ans=1;
    while(x)
    {
        int d=x%10;
        ans=ans*run(d)%mod;
        x=x/10;
    }
    printf("%d\n",ans);
}

J-牛牛喜欢字符串

做法:水题,记录每个串内的位置字符个数,总个数减去最大的数即可。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const double pi=acos(-1);
inline ll read()
{
    ll x=0,w=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
    return w==1?x:-x;
}
const int N=1e6+10;
char s[N];
int dp[N][26],n,k;
int main()
{
    n=read(),k=read();
    scanf("%s",s+1);
    int tot=n/k;
 
    for(int i=1;i+k-1<=n;i=i+k){
        for(int j=1,t=i;j<=k;++j,++t){
            dp[j][s[t]-'a']++;
        }
    }
 
    ll ans=0;
    for(int i=1;i<=k;++i){
        int mx=0;
        for(int j=0;j<26;++j) mx=max(mx,dp[i][j]);
        ans+=tot-mx;
    }
    printf("%lld\n",ans);
}

 

提供了一个详细的MATLAB仿真程序,用于实现自回归(AR)模型的功率谱估计。该程序基于经典的数字信号处理教材——《数字信号处理理论、算法与实现》第三版中的相关内容(第545-547页),旨在帮助学习者理解和实践AR模型在功率谱估计中的应用。 简介 AR模型是一种常用的时间序列分析方法,通过建立当前值与其过去值之间的线性关系来描述时间序列的动态特性。功率谱估计是信号处理中的关键环节,用于揭示信号频率成分的分布。本仿真通过自相关方法实现AR模型参数的估计,并进而计算信号的功率谱。 特点 含详细注释:代码中添加了丰富的注释,便于初学者理解每一步的计算逻辑和目的。 参数可调:用户可根据需要调整AR模型的阶数(p值)、信号长度等参数,以适应不同的信号分析需求。 理论联系实际:通过将书本知识转化为实践操作,加深对AR模型及其在功率谱估计中应用的理解。 使用说明 环境要求:确保你的计算机上已安装MATLAB,并且版本适合运行提供的脚本。 加载脚本:将提供的MATLAB文件导入到MATLAB的工作环境中。 修改配置:根据需要修改代码中的参数配置,如AR模型的阶数等。 运行仿真:执行脚本,观察并分析输出结果,包括自回归模型的系数以及估算出的功率谱。 学习与分析:通过对比不同参数下的结果,深入理解AR模型在功率谱估计中的行为。 注意事项 在使用过程中,可能需要基础的数字信号处理知识以便更好地理解代码背后的数学原理。 请确保你的MATLAB环境已正确设置,能够支持脚本中的所有函数和运算。 结论 此资源对于研究信号处理、通信工程或是进行相关学术研究的学生和科研人员来说是一个宝贵的工具。它不仅提供了理论知识的具体实现,也是提升实践技能的优秀案例。通过动手操作,你将更加熟练地掌握AR模型及其在功率谱估计中的应用技巧。 开始探索,深入了解AR模型的力量,解开信号隐藏的秘密吧!
根据用户提供的关键词“小A 弹吉他 牛客牛客网 小白 108 比详情 参攻略”,以下是整合后的相关信息和建议: --- ### 关于小白108的比详情 小白是由牛客网主办的一系列面向编程爱好者的在线竞之一。第108场事通常会围绕算法、数据结构以及实际问题解决能力展开挑战。比题目可能涉及但不限于字符串处理、动态规划、图论等领域。 对于与“小A弹吉他”相关的具体题目,可能是某道以音乐或乐器为主题的趣味性算法题。这类题目往往需要结合数学建模能力和逻辑推理技巧来完成解答。 --- ### 如何准备此类比? #### 方法一:熟悉常见算法模板 确保掌握基础的数据结构(如栈、队列)及经典算法模型(例如深度优先搜索DFS、广度优先搜索BFS)。针对可能出现的音符序列匹配或者节奏计算等问题提前复习KMP模式匹配法等相关知识点。 #### 方法二:模拟真实考场环境练习 利用过往的小白记录进行刷题训练,在规定时间内尝试独立解决问题从而提升临场发挥平。同时注意控制提交频率避免因超时错误而扣分过多。 #### 方法三:学习优秀选手思路分享 访问牛客社区查看往届高排名玩家的经验贴。他们可能会提到如何快速理解复杂描述型试题的方法论;也可能提供一些特别好用但容易被忽略掉的小技巧比如调试输出设置等细节优化方案。 --- ### 示例代码片段供参考(假设存在一个简单版本的问题) 如果遇到类似判断两个旋律是否相同类型的程序设计,则可以考虑如下实现方式: ```python def is_same_melody(melody_a, melody_b): return melody_a == melody_b melody_A = list(map(int, input().split())) melody_B = list(map(int, input().split())) if len(melody_A) != len(melody_B): print("No") else: if is_same_melody(melody_A,melody_B): print("Yes") else: print("No") ``` 此段落仅为示意用途,请依据实际情况调整适应不同难度等级下的业务场景需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长沙大学ccsu_deer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值