C++知识点总结(54):复杂模拟综合

news2024/9/20 16:57:01

复杂模拟综合

  • 例题
    • 1. 玩具谜题
    • 2. 猴子兄弟爬山
    • 3. 浇水
    • 4. 数组旋转
    • 5. 石头剪刀布
    • 6. 巨石滚滚

例题

1. 玩具谜题

小南有一套可爱的玩具小人,它们各有不同的职业。
有一天,这些玩具小人把小南的眼镜藏了起来。 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图:
请添加图片描述
这时 singer 告诉小南一个谜题:“眼镜藏在我左数第 3 3 3 个玩具小人的右数第 1 1 1 个玩具小人的左数第 2 2 2 个玩具小人那里。”
小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向;而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向。
小南一边艰难地辨认着玩具小人,一边数着:
singer 朝内,左数第 3 3 3 个是 archer;
archer 朝外,右数第 1 1 1 个是 thinker;
thinker 朝外,左数第 2 2 2 个是 writer。
所以眼睛藏在 writer 里。
虽然成功找回了眼镜,但小南并没有放心。 如果下次有更多的玩具小人藏他的眼镜,或是谜題的长度更长,他可能就无法找到眼镜了。所以小南希望你写程序帮他解决类似的谜題。这样的谜題具体可以描述为:
n n n 个玩具小人围成一圈,已知它们的职业和朝向。现在第 1 1 1 个玩具小人告诉小南一个包含 m m m 条指令的谜題,其中第 z z z 条指令形如"左数/右数第 s s s 个玩具小人"。你需要输出依次数完这些指令后,到达的玩具小人的职业。

答题技巧:

  1. 遇到循环的圈,数组尽量从 0 0 0 编号(只要对下标操作,就从 0 0 0 存)
  2. 尽量不要在结构体里面定义字符串,可能会有错误(malloc 分配空间的错误)
  3. 遇到循环的圈,在更新下标的时候一定要记得加上 n n n 在模 n n n(考虑负数的情况)

参考答案:

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int a;
    char s[105];
}a[100010];
int n,m,d,s,idx;
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++)cin>>a[i].a>>a[i].s;
    while(m--){
        cin>>d>>s;
        if(d==0){
            if(a[idx].a==0)idx=(idx-s+n)%n;
            else idx=(idx+s)%n;
        }else{
            if(a[idx].a==0)idx=(idx+s)%n;
            else idx=(idx-s+n)%n;
        }
    }
    cout<<a[idx].s;
    return 0;
}

2. 猴子兄弟爬山

已知皮皮和大智是关系非常友好的两只猴子,并且它们都居住在同一座山上。山高 h h h 米,皮皮在距离山脚 h a h_a ha 米的地方居住,大智在距离山脚 h b h_b hb 米的地方居住。
皮皮和大智相约爬山,它们约定从同一天的白天开始从自己居住的地方开始往山顶爬,每天皮皮和大智都会根据自己的实际情况决定自己的行为:

  • 白天正常情况下,皮皮每天爬 u a u_a ua 米,大智每天爬 u b u_b ub 米,但是如果白天开始时对方比自己高,那么皮皮会多爬 a d d a add_a adda 米,大智会多爬 a d d b add_b addb 米。
  • 黑夜正常情况下,皮皮每天掉 d a d_a da 米,大智每天掉 d b d_b db 米,但是如果黑夜开始时对方比自己高,那么皮皮会少掉 s u b a sub_a suba 米,大智会少掉 s u b b sub_b subb 米。

现在请你帮助计算皮皮和大智两只猴子都爬到山顶所需要的时间(天数),你需要回答 t t t 个这样的问题。数据数据保证两人一定能够在有限步数内登上山顶。

答题技巧:

  1. 分段、贪心,努力逼近最优解
  2. 注意特殊判断,及时终止(也可以设极端值实现)

参考答案:

#include<bits/stdc++.h>
using namespace std;
int t,h,ha,hb,ua,ub,adda,addb,da,db,suba,subb;
int main(){
    cin>>t;
    while(t--){
        cin>>h>>ha>>hb>>ua>>ub>>adda>>addb>>da>>db>>suba>>subb;
        int day=0;
        while(ha<h||hb<h){
            day++;
            if(ha>hb)hb+=addb;
            else if(hb>ha)ha+=adda;
            ha+=ua,hb+=ub;
            if(ha>=h)ha=1e9;
            if(hb>=h)hb=1e9;
            if(ha>hb)hb+=subb;
            else if(hb>ha)ha+=suba;
            ha-=da,hb-=db;
        }
        cout<<day<<endl;
    }
    return 0;
}

3. 浇水

皮皮和小美打算给花园里的 n n n 株植物浇水。
植物排成一行,编号从左到右依次从 1 ∼ n 1\sim n 1n。其中,第 i ( 1 ≤ i ≤ n ) i(1≤i≤n) i(1in) 株植物的位置 x = i x=i x=i,需要浇的水量为 w i w_i wi 升。皮皮和小美每人有一个水罐,其中皮皮的水罐容量为 A A A 升,小美的水罐的容量为 B B B 升,初始时,两个水罐都装满了水。
皮皮从左到右给植物浇水,从第 1 1 1 株植物开始。小美从右到左给植物浇水,从第 n n n 株植物开始。他们俩同时开始给植物浇水。
皮皮和小美各自为每株植物浇水时,每分钟浇一升水,也就是每过去一分钟,水罐中的水减少一升,植物还需要浇的水也减少一升。如果当前植物所需浇水量减为零,就移动到下一棵植物(对于皮皮是编号大一的植物,对于小美是编号小一的植物),移动的时间忽略不计。
如果浇水途中水罐中的水耗尽了,一个超强水泵会用 T T T 分钟的时间,重新灌满水罐,然后重新开始浇水。
如果某人到达一株植物时,另一个人已经先到了,那么就只让先到的人浇水。如果皮皮和小美同时到达,就让皮皮完成浇水。
请你实现一个程序,求为所有植物完成浇水的时间。

参考答案:

//超时版错因: 程序模拟了时间,但是10^11绝对超
#include<bits/stdc++.h>
using namespace std;
int n,A,B,T,w[100010];
long long l,r,a,b,ta,tb;
int main(){
    cin>>n>>A>>B>>T;
    for(int i=1;i<=n;i++)cin>>w[i];
    l=1,r=n,a=A,b=B;
    while(l<=r){
        if(ta<=tb){
            while(w[l]){
                if(a==0){
                    a=A;
                    ta+=T;
                }
                w[l]--,a--,ta++;
            }
            l++;
        }else{
            while(w[r]){
                if(b==0){
                    b=B;
                    tb+=T;
                }
                w[r]--,b--,tb++;
            }
            r--;
        }
    }
    cout<<max(ta,tb);
    return 0;
}

技巧:

  1. 解耦法
  2. 注意 ceil 的精度问题

AC 代码:

#include<bits/stdc++.h>
using namespace std;
int n,A,B,T,w[100010];
long long l,r,a,b,ta,tb;
void nextA(){
    if(a>=w[l])
        a-=w[l],ta+=w[l];
    else{
        int cnt=ceil((w[l]-a)*1.0/A);
        ta+=w[l]+1ll*cnt*T,a=((a-w[l])%A+A)%A;
    }
    l++;
}
void nextB(){
    if(b>=w[r])
        b-=w[r],tb+=w[r];
    else{
        int cnt=(w[r]-b-1)/B+1;
        tb+=w[r]+1ll*cnt*T,b=((b-w[r])%B+B)%B;
    }
    r--;
}
int main(){
    cin>>n>>A>>B>>T;
    for(int i=1;i<=n;i++)cin>>w[i];
    l=1,r=n,a=A,b=B;
    while(l<=r){
        if(ta<=tb)nextA();
        else nextB();
    }
    cout<<max(ta,tb);
    return 0;
}

4. 数组旋转

给定一个整数数组 < a 1 , a 2 , a 3 , ⋯   , a n > <a_1,a_2,a_3,\cdots,a_n> <a1,a2,a3,,an>,然后输入一系列数字 < x 1 , x 2 , x 3 , ⋯   , x m > <x_1,x_2,x_3,\cdots,x_m> <x1,x2,x3,,xm>,如果 x i > 0 x_i>0 xi>0,代表将数组中的元素向右旋转 x i x_i xi 个位置。如果 x i < 0 x_i<0 xi<0,代表将数组中的元素向左旋转 − x i -x_i xi 个位置。

技巧:向后补充,a[i+n]=a[i]

但是——暴力 YYDS!

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int val,idx;
}a[1005];
int n,m,x;
bool cmp(Node a, Node b){
    return a.idx<b.idx;
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i].val;
        a[i].idx=i;
    }
    cin>>m;
    while(m--){
        cin>>x;
        if(x>0){
            for(int i=0;i<n;i++)
                a[i].idx=(a[i].idx+x)%n;
        }else{
            for(int i=0;i<n;i++)
                a[i].idx=((a[i].idx-abs(x))%n+n)%n;
        }
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++)cout<<a[i].val<<" ";
        cout<<endl;
    }
    return 0;
}

5. 石头剪刀布

石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风靡世界。简单明了的规则,使得石头剪子布没有任何规则漏洞可钻,单次玩法比拼运气,多回合玩法比拼心理博弈,使得石头剪子布这个古老的游戏同时用于“意外”与“技术”两种特性,深受世界人民喜爱。
游戏规则:石头打剪刀(用 G 表示石头),布包石头(用 C 表示布),剪刀剪布(用 P 表示剪刀)。
现在有 2 n 2n 2n 名选手进行两两猜拳,一共进行 m m m 轮,选手编号为 1 ∼ 2 n 1\sim 2n 12n,初始时,所有选手的排名按照编号从小到大排列。小猴有预知未来的能力,知道第 j j j 轮中编号为 i i i 的选手出结果为 g i , j g_{i,j} gi,j,其中 g i , j g_{i,j} gi,j 为 G、C、P 三者之一。
每轮比赛中共会进行 n n n 场比赛,都是让最新的排名(按照分数从高到低排序,如果有分数相同的情况,则按编号从小到大排序)中的第 1 1 1 名与第 2 2 2 名比赛(第一场比赛)、第 3 3 3 名与第 4 4 4 名比赛(第二场比赛)、

…、第 2 k − 1 2k−1 2k1 名与第 2 k 2k 2k 名比赛(第 k k k 场比赛,其中 1 ≤ k ≤ n 1≤k≤n 1kn)。
每场比赛中的结果均为:
一名选手获胜,另一名选手输,获胜方选手得 1 1 1 分,输得一方选手不得分;
双方平局,双方选手均不得分。
小猴因为使用超能力预知每名选手出的结果,现在需要休息,所以请你计算并输出第
m m m 轮结束时所有人的排名,即按照分数从高到低输出每名选手的编号,如果有分数相同的情况,则优先输出编号更小的选手。

技巧:重载运算符。

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int id,score;
    bool operator<(const Node& rhs) const {
        if(score!=rhs.score)return score>rhs.score;
        return id<rhs.id;
    }
}a[2010];
int n,m;
char g[2010][2010];
bool check(char a,char b){
    if(a=='G'&&b=='P')return 1;
    if(a=='C'&&b=='G')return 1;
    if(a=='P'&&b=='C')return 1;
    return 0;
}
int main(){
    cin>>n>>m;
    n*=2;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cin>>g[i][j];
        a[i].id=i;
    }
    for(int j=1;j<=m;j++){
        for(int i=1;i<=n;i+=2){
            int x=a[i].id,y=a[i+1].id;
            a[i].score+=check(g[x][j],g[y][j]);
            a[i+1].score+=check(g[y][j],g[x][j]);
        }
        sort(a+1,a+n+1);
    }
    for(int i=1;i<=n;i++)cout<<a[i].id<<endl;
    return 0;
}

6. 巨石滚滚

小猴最近在一款非常火热的游戏“巨石滚滚”,游戏中某一个关卡难住了小猴。具体来说,该关卡
给定一个 n × m n×m n×m 的矩阵,矩阵中包含三种类型的单元格:

  • 空单元格,用 . 表示;
  • 一块巨石,用 * 表示;
  • 一个障碍物,用 # 表示。

游戏开始时,所有巨石都会掉落下来(第一行最高,第 n n n 行最低),直到碰到地板(第 n n n 行)、障碍物或其他已经无法移动的巨石才会停止掉落。
现在给定矩阵中每个单元格的初始状态,即每个单元格可能为空、有一块巨石或有一个障碍物,请你帮助小猴计算矩阵中所有单元格的最终状态。

//超时代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
char a[2010][2010];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    for(int i=n-1;i>=1;i--)
        for(int j=1;j<=m;j++)
            if(a[i][j]=='*'){
                int t=i,idx=i;
                while(idx<n&&a[idx+1][j]=='.')idx++;
                a[t][j]='.',a[idx][j]='*';
            }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cout<<a[i][j];
        cout<<endl;
    }
    return 0;
}

技巧:填坑法

AC 代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
char a[2010][2010];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    for(int j=1;j<=m;j++){
        int down=n;
        for(int i=n;i>=1;i--)
            if(a[i][j]=='*')
                swap(a[i][j],a[down--][j]);
            else if(a[i][j]=='#')
                down=i-1;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cout<<a[i][j];
        cout<<endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

llm 是泡沫?

这篇文章不谈技术&#xff0c;只想聊聊自己这两年从事 llm 工作的一些感悟。 我个人对 llm 是一种很复杂的态度。毕竟&#xff0c;它真的击碎了我 2023 年之前所有的技术积累&#xff0c;以前在 nlp 苦心钻研的训练经验、模型结构、不同任务类型的不同处理技巧&#xff0c;好像…

个微管理撤回删除的消息都可以查看

有没有经历过误删微信消息的尴尬时刻&#xff1f;&#x1f605;或者想知道撤回的消息到底是什么内容&#xff1f;今天&#xff0c;我要向大家推荐一个多功能微管理神器&#xff0c;帮你轻松解决这些问题&#xff01;&#x1f4aa;&#x1f48c; 1️⃣ 多个账号同时在线 &#x…

nefu暑假集训3 并查集与最小生成树 个人模板+例题汇总

前言&#xff1a; 并查集与最小生成树的训练。 正文&#xff1a; 链接&#xff1a;并查集与最小生成树 - Virtual Judge (vjudge.net) 题目&#xff1a; A - 关押罪犯&#xff1a; #include <bits/stdc.h> using namespace std; const int N200005; int fa[N],d[N]; …

实现一个能设置MaxLine的LayoutManager

实现一个能设置MaxLine的LayoutManager 有时候&#xff0c;我们会遇到这种需求&#xff1a;一个线性的列表布局&#xff0c;当item量很少的时候&#xff0c;就是wrap_content直接展示完所有item&#xff0c;但是当item数量超过某个数时就要固定高度&#xff0c;让其变成可滑动…

AOP 面向切片编程

目录 1. 什么是AOP 2. AOP的应用场景 3. AOP在Java中的实现 4. Spring AOP概述 5. Spring AOP的配置 1.在pom.xml文件中添加Spring AOP的依赖&#xff1a; 2. 定义切面 3. 启用AOP 4. 目标类 5. 测试AOP 6. AOP与其他技术的对比 面向切面编程&#xff08;AOP, Aspec…

SPI通信(软件模拟)

1 软件SPI程序框架 2 软件SPI交换一个字节的先后顺序 3 读取W25q64芯片厂商ID,设备ID 4 宏定义W26q64指令码 5 页缓冲区最大256字节&#xff0c;超过就会忙碌 6 页编程

生产环境中变态开启devtools(强制)

写到最前面 首先&#xff0c;你已经下载了google的插件【vue devtools】&#xff0c;不知道怎么下载&#xff0c;留言博主 如果你想看的项目中的vuetools插件打开是这样的 Vue.js is detected on this page. Devtools inspection is not available because it’s in product…

【中学教资-信息技术】多媒体文件大小的存储

图像/音频/视频文件大小的计算 1 图像文件2 音频文件3 视频文件4 例题5 总结 视频讲解&#xff1a;音频文件大小/视频文件大小计算-失舵之舟 1 图像文件 压缩比原始大小/被压缩之后大小 颜色深度&#xff1a;指图像中每个像素所占的二进制位数&#xff08;bit&#xff09; n位…

BioXM一款实用的生物小软件

软件介绍 BioXM是一款非常简单明了的分子生物学软件&#xff0c;全中文操作界面非常友好。 DNA序列分析、蛋白质序列分析、多序列比对、氨基酸相似性计算、酶切位点分析、ORF分析、分子量和等电点预测、序列数据库等。 软件下载 https://pan.quark.cn/s/84df485efd6e安装教…

Vxe UI vue vxe-table 如何在表格中使用上传附件、上传图片

Vxe UI vue vxe-table 如何在表格中使用上传附件、上传图片 效果图 在表格中显示缩略图模式上传附件或图片 点击更多按钮查看全部 鼠标拖动上传 代码 <template><div><vxe-grid v-bind"gridOptions"></vxe-grid></div> </tem…

第九周:机器学习

目录 摘要 Abstract 一、RNN 1、引入 2、RNN的分类 二、LSTM 1、基本结构 2、具体步骤 3、举例说明 4、原理理解 总结 摘要 本周主要围绕RNN进行探讨&#xff0c;从为什么需要这类”循环网络“入手&#xff0c;提到了”slot filling“技术&#xff0c;接着又对R…

大模型赋能风控运营:效率跃升的密码

一、大模型助力风控运营的背景与趋势 大模型兴起的背景 随着金融行业的迅速发展和数据量的爆炸式增长&#xff0c;传统的风控运营手段逐渐难以满足复杂多变的风险形势。大数据、人工智能等技术的不断进步&#xff0c;为大模型在风控运营领域的应用提供了技术支撑。金融机构面…

海洋大地测量基准与水下导航系列之一引子

海底大地基准网是一组布放在海底的声学基准站&#xff0c;组建类似GNSS星座的定位系统&#xff0c;既可以对水面及水下的各类设备提供时间和空间信息&#xff0c;也可用来监测海底板块及水体环境的动态变化。海底声学基准站与海面GNSS、海底重力站联合打造立体的观测控制网&…

十道MySQL必问面试题

你是如何理解最左前缀原则的&#xff1f;你是如何理解行锁、GAP锁、临键锁的&#xff1f;你是如何理解MVCC的&#xff1f;你是如何理解count(*)和count(1)的&#xff1f;你是如何理解Online DDL的&#xff1f;你知道哪些情况下会导致索引失效&#xff1f;你是如何理解filesort的…

fastmock使用

FastMock 是一个在线工具&#xff0c;用于快速创建和管理模拟 API&#xff08;Mock API&#xff09;。它主要用于前端开发&#xff0c;允许开发者在没有真实后端服务的情况下&#xff0c;模拟 API 响应&#xff0c;从而加速开发和测试过程。 FastMock网址&#xff1a;fastmock.…

Java多进程调用dll程序和exe程序

&#x1f3af;导读&#xff1a;本文介绍了使用Java调用本地DLL及EXE程序的方法。针对DLL调用&#xff0c;文章提供了基于Java Native Access (JNA) 库的具体实现方案&#xff0c;包括定义Java接口以映射DLL中的函数&#xff0c;并展示了如何加载DLL及调用其中的方法。对于EXE程…

Python 数据可视化:工具与实践

文章目录 数据可视化可视化库特点对比实例&#xff1a;绘制基本数据分布图评估维度 交互式可视化与静态图表实例&#xff1a;创建交互式折线图评估维度 实时数据可视化实例&#xff1a;展示实时股票数据评估维度 图表设计原则实例&#xff1a;设计适合展示销售数据的条形图评估…

论文辅助笔记:LP_BERT

1 train_task1.py 1.1 main部分 读取命令行参数&#xff0c;调用task1函数 1.2 task1 train 1.3 task1 valid 1.3 collate_fn 2 Dataset 2.1 train dataset 2.2 valid dataset 3 LPBERT 3.1 不同的embedding day-of-week embedding和time-of-day embedding X位置和Y位置的…

色彩与笔触的交响:广州米塔在线科教技术有限公司揭秘PS绘画秘籍!

在数字艺术的广阔天地里,PS无疑是一颗璀璨的明星&#xff0c;它不仅在图像处理领域独领风骚&#xff0c;更以其强大的功能成为了众多艺术家和设计师进行数字绘画的首选工具。广州米塔在线科教技术有限公司&#xff0c;作为致力于艺术教育与技术分享的平台&#xff0c;深知掌握P…

sealos快速搭建k8s集群

一&#xff0c;环境准备 1&#xff0c;三台&#xff08;搭建一主两从集群&#xff09;或五台&#xff08;三主两从集群&#xff09;虚拟机&#xff0c; 安装alimaLinux系统 &#xff0c;相同的root密码&#xff0c;不要安装docker。 如果是alimaLinux-mini版本操作系统&#xf…