模拟算法 蓝桥杯备赛系列 acwing

news2025/1/19 11:12:54

文章目录:

基础知识


什么是模拟?


例题



一、错误票据

1.解题思路

2.代码


二、移动距离


1.解题思路

2.代码


三、航班时间


1.解题思路

2.代码

四、外卖优先级

1.解题思路

2.代码

前面为了目录好看大家就当个玩笑看吧哈哈哈。下面上正文。

                                              正文

基础知识
什么是模拟?
模拟一个很宽泛的内容,比如字符串处理,日期处理。凡是不是很复杂但是没有标准归类的题目都可以称为模拟。

枚举和模拟是没有什么算法可言的,按照题目说的意思去模拟一下即可,要求对语法代码的熟练度比较高。

模拟题是有唯一解的,而不是求最优解的问题,只不过模拟题实现起来比较麻烦。

      这个是引用某个大佬的内容: 模拟算法是一种最基本的算法思想,是对程序员基本编程能力的一种考查,其解决方法就是根据题目给出的规则对题目要求的相关过程进行编程模拟。在解决模拟类问题时,需要注意字符串处理、特殊情况处理和对题目意思的理解。我们知道在C语言中,通常使用函数srand()和rand()来生成随机数。其中函数srand()用于初始化随机数发生器,然后使用函数rand()来生成随机数。如果要使用上述两个函数,则需要在源程序头部包含time.h文件。在程序设计过程中,可使用随机函数来模拟自然界中发生的不可预测情况。在解题时,需要仔细分析题目给出的规则,要尽可能地做到全面地考虑所有可能出现的情况,这是解模拟类问题的关键点。

二、错误票据
1.解题思路

步骤:
①输入:都输入到一个数组中

本题比较坑的是注意输入,只告诉了有多少行,没告诉每行有多少个数。每行有多少个数需要自己处理 。

int a[100010];    
int k=0;
int x;
while(cin>>x)  //这行会把每个出现的数都存到a[]数组中
{
    a[k++]=x;
}

②从小到大排序

③循环遍历数组

找重号:如果相邻两个数相等,那么这个就是重号

找断号 :如果相邻的两个数相差2,那么两数中间的就是断号

2.代码

做题先暴力,下面是暴力代码

//另一种方法:暴力模拟法

#include <iostream>
#include <algorithm>
using namespace std;
int a[100010];
int main()
{
    int n;
    cin>>n;
    
    int k=0;
    
    //第一步:输入数据,合并到一个数组中
    int x;
    while(cin>>x)
    {
        a[k++]=x;
    }
   // for(int i=0;i<k;i++) cout<<a[i]<<" ";
   
   //第二步:排序
   sort(a,a+k);
   
   //第三步:求重号:利用桶的思想,找到第一个重复的数据,记录
   int t[100010],ans2=0;
   for(int i=0;i<k;i++)
   {
       t[a[i]]++;
   }
   for(int i=0;i<=100000;i++)
   {
       if(t[i]>=2)
       {
           ans2=i;
           break;
       }
   }
    
    //第四步:求断号:先给序列去重,再利用下标和排好序的序列,找断号,注意边界
    int z[100010],j=0;
    for(int i=0;i<k;i++)
    {
        if(a[i]==a[i-1]) continue;
        else z[j++]=a[i];
    }
    //for(int i=0;i<j;i++) cout<<z[i]<<" ";
    int q=z[0],ans1=0;
    for(int i=0;i<j;i++)
    {
        if(z[i]==q) 
        {
            q++;
            continue;   
        }
        else 
        {
            ans1=q;
            break;
        }
        
    }
    
    cout<<ans1<<" "<<ans2;
    
    return 0;
    
}


下面这是正常做法 

#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 10010;

int n;
int a[N];

int main()
{
    int cnt;
    cin >> cnt;
    string line;

    getline(cin, line); // 忽略掉第一行的回车
    while (cnt -- )
    {
        getline(cin, line);
        stringstream ssin(line);

        while (ssin >> a[n]) n ++ ;
    }

    sort(a, a + n);

    int res1, res2;
    for (int i = 1; i < n; i ++ )
        if (a[i] == a[i - 1]) res2 = a[i];  // 重号
        else if (a[i] >= a[i - 1] + 2) res1 = a[i] - 1; // 断号

    cout << res1 << ' ' << res2 << endl;

    return 0;
}

二、移动距离
1.解题思路

题目中遇到距离一般有两种:曼哈顿距离 和 欧几里得距离

曼哈顿距离:|x1-x2|+|y1-y2| 两点之间走过的折线距离
欧几里得距离:sqrt((x1-x2) * (x1-x2)+(y1-y2) * (y1-y2)) 两点间的直线距离

本题所有点的坐标其实就是行号和列号

可以借鉴c++中二维数组的行号和列号下标表示:让编号从0开始标号,所以让m,n一开始都-1,不需要特判边界了。所以 行号:n/w m/w ,列号:n%w m%w

又因为本题编号是蛇形递增+1的,所以只需要判断是奇数行还是偶数行

偶数行不用变,奇数行逆序:if n/w 是奇数 ,w-1-n%w
2.代码

//时间复杂度O(1)
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int w, m, n;
    cin >> w >> m >> n;
    m --, n -- ; //让编号从0开始

    int x1 = m / w, x2 = n / w;  //两个点的行号
    int y1 = m % w, y2 = n % w;  //两个点的列号
    if (x1 % 2) y1 = w - 1 - y1; //第一个点行号如果是奇数行,列号就反转一下
    if (x2 % 2) y2 = w - 1 - y2; //第二个点行号如果是奇数行,列号就反转一下

    cout << abs(x1 - x2) + abs(y1 - y2) << endl;  //求出两点之间的曼哈顿距离

    return 0;
}
三、航班时间
1.解题思路

通过分析,可以得到:

飞行时间=[(去的结束时间-去的起始时间)+(回的结束时间-回的起始时间)]/2

步骤:

①字符串格式化输入:这道题目麻烦就是麻烦在字符串的格式处理上

getline(cin,line);//忽略第一行的回车
int fh1,fm1,fs1,fh2,fm2,fs2,fd=0;
scanf("%d:%d:%d %d:%d:%d (+%d)",&fh1,&fm1,&fs1,&fh2,&fm2,&fs2,&fd);//注意输入时(+%d),不匹配后就会跳过了

②将所有时间转化为距离当天00:00:00的秒数,得到飞行时间秒数time

int time1,time2,t;
time1=fd*24*3600+fh2*3600+fm2*60+fs2-(fh1*3600+fm1*60+fs1);
time2=ed*24*3600+eh2*3600+em2*60+es2-(eh1*3600+em1*60+es1);
t=(time1+time2)/2;

③再将飞行时间time转化为00:00:00这一规定时间格式:

hour=time/3600;
minute=time%3600/60
second=time%3600%60

④格式化输出:

printf("%02d:%02d:%02d\n", t/3600, t%3600/60, t%3600%60);

2.代码

#include<iostream>
#include <cstdio>
using namespace std;

int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        //输入去的时候起始时间和结束时间
        int fh1,fm1,fs1,fh2,fm2,fs2,fd=0;
        scanf("%d:%d:%d %d:%d:%d (+%d)",&fh1,&fm1,&fs1,&fh2,&fm2,&fs2,&fd);
        
        //输入回的时候起始时间和结束时间
        int eh1,em1,es1,eh2,em2,es2,ed=0;
        scanf("%d:%d:%d %d:%d:%d (+%d)",&eh1,&em1,&es1,&eh2,&em2,&es2,&ed);
        
        //计算两次分别的飞行时间,和除以2为最终的飞行时间
        int time1,time2,t;
        time1=fd*24*3600+fh2*3600+fm2*60+fs2-(fh1*3600+fm1*60+fs1);
        time2=ed*24*3600+eh2*3600+em2*60+es2-(eh1*3600+em1*60+es1);
        t=(time1+time2)/2;
        
        //将秒数转化为规定格式输出
        printf("%02d:%02d:%02d\n", t/3600, t%3600/60, t%3600%60);
    }
    return 0;
}
//封装为函数

#include<iostream>
#include<cstdio>
using namespace std;
int getTime()
{
    int h1,m1,s1,h2,m2,s2,d=0;
    scanf("%d:%d:%d %d:%d:%d (+%d)",&h1,&m1,&s1,&h2,&m2,&s2,&d);
    int time=d*24*3600+h2*3600+m2*60+s2-(h1*3600+m1*60+s1);
    return time;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int i = 0; i < t; i++)
    {
        int time1=getTime();
        int time2=getTime();
        int t=(time1+time2)/2;
        printf("%02d:%02d:%02d\n", t/3600, t/60%60, t%60);
    }
    return 0;
}
四、外卖优先级
1.解题思路

在这里插入图片描述

伪代码如下:

score[i]:表示第i个店铺当前的优先级 
last[i]: 表示第i个店铺上一次有订单的时刻
st[i]:表示第i个店铺当前是否处于优先缓存中

将所有订单按时间顺序排序;
for 每个订单
{
    每次处理一批相同的订单;
    id,t,cnt;
    //第一部分,是上一个拿到订单的时间last[id]和t之间,中间没订单所以要−1,没订单的数量是t−last[i]−1 (比如第3和第6时刻都有订单,没有订单的时候就是4,5)
    score[id]=t-last[id]-1;
    if(score[id]<0) score[id]=0;//计算优先权,如果为负值更新为0。如果小于等于3,更新优先缓存 st[id]=false
    if(score[id]<=3) st[id]=false;
    
    //第二部分,是此时,tt时刻拿到订单,并且拿到的数量为cntcnt,要加上2∗cnt
    score[id]+=cnt*2;
    if(score[id]>5) st[id]=true;//计算优先权,如果大于5,更新优先缓存 st[id]=true
}
for(int i=1;i<=n;i++)
{
    if(last[i]<T) 
    {
        score[i]-=T-last[i];
        if (score[i] <= 3) st[i] = false;
    }
}

res = 0;
for(int i=1;i<=n;i++)
{
    res+=st[i];
}

2.代码 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 100010;

int n, m, T;
int score[N], last[N];
bool st[N];

PII order[N];

int main()
{
    scanf("%d%d%d", &n, &m, &T);
    for (int i = 0; i < m; i ++ ) scanf("%d%d", &order[i].x, &order[i].y);
    sort(order, order + m);

    for (int i = 0; i < m;)
    {
        int j = i;
        while (j < m && order[j] == order[i]) j ++ ;
        int t = order[i].x, id = order[i].y, cnt = j - i;
        i = j;
/*
while (j < m && order[j] == order[i]) j ++ ;和cnt = j - i;是为了算出来同一时刻同一家店的订单数量,数量就是cnt的值,这个数量可能不唯一。
第一次while()循环中的order[j] == order[i]是一定成立的,然后j ++,j 就变成 i + 1,再比较order[i]和order[i + 1]是否相等,含义就是下一个订单与当前这个订单是不是同一时刻同一家店的,直到时刻或者 id 不同时,结束while循环,最后 j 就指向“不重复”的第一个订单,然后令 i = j,继续枚举所有订单
写成:int j = i + 1;,其它语句都不改动,也是对的,我感觉更好理解
*/
        
        score[id] -= t - last[id] - 1;
        if (score[id] < 0) score[id] = 0;
        if (score[id] <= 3) st[id] = false; 

        score[id] += cnt * 2;
        if (score[id] > 5) st[id] = true;

        last[id] = t;
    }

    for (int i = 1; i <= n; i ++ )
        if (last[i] < T)
        {
            score[i] -= T - last[i];
            if (score[i] <= 3) st[i] = false;
        }

    int res = 0;
    for (int i = 1; i <= n; i ++ ) res += st[i];

    printf("%d\n", res);

    return 0;
}

最近博主有事,暂且停更,一天一篇博客确实很有压力的,所以说待博主沉淀亿下给大家更多优质内容哈哈哈!元旦过后见! 

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

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

相关文章

码住!8个小众宝藏的开发者学习类网站

1、simplilearn simplilearn是全球排名第一的在线学习网站&#xff0c;它的课程由世界知名大学、顶级企业和领先的行业机构通过实时在线课程设计和提供&#xff0c;其中包括顶级行业从业者、广受欢迎的培训师和全球领导者。 2、VisuAlgo VisuAlgo是一个免费的在线学习算法和数…

Nginx直播服务器搭建及推拉流测试

文章目录 前言一、搭建 Nginx 直播服务器1、安装 Nginx 依赖2、下载并解压源码①、下载并解压 nginx-http-flv-module 直播模块源码②、下载并解压 Nginx 源码 3、编译安装4、配置 rtmp 服务①、添加 rtmp 服务②、验证配置 二、推流、拉流测试1、ffmepg 推流2、VLC 拉流 前言 …

【汇编笔记】初识汇编-内存读写

汇编语言的由来&#xff1a; CPU是计算机的核心&#xff0c;由于计算机只认识二进制&#xff0c;所以CPU执行的指令是二进制。 我们要想让CPU工作&#xff0c;就得给他提供它认识的指令&#xff0c;这一系列的指令的集合&#xff0c;称之为指令集。 指令集&#xff1a; 不同的体…

PyTorch深度学习实战(28)——对抗攻击(Adversarial Attack)

PyTorch深度学习实战&#xff08;28&#xff09;——对抗攻击 0. 前言1. 对抗攻击2. 对抗攻击模型分析3. 使用 PyTorch 实现对抗攻击小结系列链接 0. 前言 近年来&#xff0c;深度学习在图像分类、目标检测、图像分割等诸多领域取得了突破性进展&#xff0c;深度学习模型已经能…

React学习计划-React16--React基础(七)redux使用与介绍

笔记gitee地址 一、redux是什么 redux是一个专门用于做状态管理的js库&#xff08;不是react插件库&#xff09;它可以用在react、angular、vue的项目中&#xff0c;但基本与react配合使用作用&#xff1a;集中式管理react应用中多个组件共享的状态 二、什么情况下需要使用r…

go 源码解读 - sync.Mutex

sync.Mutex mutex简介mutex 方法源码标志位获取锁LocklockSlowUnlock怎么 调度 goroutineruntime 方法 mutex简介 mutex 是 一种实现互斥的同步原语。&#xff08;go-version 1.21&#xff09; &#xff08;还涉及到Go运行时的内部机制&#xff09;mutex 方法 Lock() 方法用于…

0.1+0.2≠0.3,揭秘Python自带的Bug

朋友们&#xff0c;问一个简单的问题&#xff1a;0.10.2&#xff1f; 你肯定会说&#xff1a;中国人不骗中国人&#xff0c;0.10.20.3。 但是在Python里&#xff0c;0.10.2≠0.3 &#xff0c;我们今天一起来看看这个&#xff0c;并且看一下解决办法。 离奇的错误 在python里…

解决ELement-UI懒加载三级联动数据不回显(天坑)

最老是遇到这类问题头有点大,最后也是解决了,为铁铁们总结了一下几点 一.查看数据类型是否一致 未选择下 选择下 二.处理数据时使用this.$set方法来动态地设置实例中的属性&#xff0c;以确保其响应式 三.绑定v-if 确保每次重新加载 四.绑定key 五.完整代码

台阶仪在半导体行业中的广泛应用及其重要意义

台阶仪在半导体材料的表征和研究中是一种非常重要的工具。如在半导体材料的制备过程中&#xff0c;一些关键的工艺参数&#xff0c;如温度、压力、气氛等条件的变化&#xff0c;会导致半导体材料的能带结构发生变化&#xff0c;通过使用台阶仪&#xff0c;可以准确测量和分析材…

菜鸟学习vue3笔记-vue hooks初体验

import { ref } from "vue"; export default function () {let a1 ref(1);let a2 ref(5);let c ref(0);function add() {a1.value;a2.value;}return {add,a1,a2,c,}; }<template><div><p>第一个数字{{ a1 }}</p><p>第二个数字{{ a2…

解密Python高级特性:深度探讨装饰器与上下文管理器的魔法

写在开头 在Python编程的奇妙世界里,有两个被誉为编程魔法的特性:装饰器和上下文管理器。它们不仅如同纹章和护盾般赋予代码强大的能力,更是提升代码优雅性和可维护性的法宝。本篇文章将深入研究这两项高级特性,揭示它们的神秘面纱,同时通过丰富的实例展示它们的多样应用…

用C的递归函数求n!-----(C每日一编程)

用递归函数求n&#xff01; 有了上面这个递归公式就能写C代码了。 参考代码&#xff1a; int fac(int n) {if (n 1 || n 0)return 1;else return n * fac(n - 1); } void main() {int n;scanf("%d",&n);int f fac(n);printf("\n%d!%d\n", n, f); …

[Angular] 笔记 11:可观察对象(Observable)

chatgpt: 在 Angular 中&#xff0c;Observables 是用于处理异步数据流的重要工具。它们被广泛用于处理从异步操作中获取的数据&#xff0c;比如通过 HTTP 请求获取数据、定时器、用户输入等。Observables 提供了一种机制来订阅这些数据流&#xff0c;并可以在数据到达时执行相…

python实现一维傅里叶变换——冈萨雷斯数字图像处理

原理 傅立叶变换&#xff0c;表示能将满足一定条件的某个函数表示成三角函数&#xff08;正弦和/或余弦函数&#xff09;或者它们的积分的线性组合。在不同的研究领域&#xff0c;傅立叶变换具有多种不同的变体形式&#xff0c;如连续傅立叶变换和离散傅立叶变换。最初傅立叶分…

Python初学者必须吃透的69个内置函数!

所谓内置函数&#xff0c;就是Python提供的, 可以直接拿来直接用的函数&#xff0c;比如大家熟悉的print&#xff0c;range、input等&#xff0c;也有不是很熟&#xff0c;但是很重要的&#xff0c;如enumerate、zip、join等&#xff0c;Python内置的这些函数非常精巧且强大的&…

docker学习(二十一、network使用示例container、自定义)

文章目录 一、container应用示例1.需要共用同一个端口的服务&#xff0c;不适用container方式2.可用示例3.停掉共享源的容器&#xff0c;其他容器只有本地回环lo地址 总结 二、自定义网络应用示例默认bridge&#xff0c;容器间ip通信默认bridge&#xff0c;容器间服务名不通 自…

FPGA高端项目:SDI 视频+音频编解码,提供工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的 GT 高速接口解决方案我目前已有的SDI编解码方案 3、设计思路和框架设计框图GV8601A均衡EQGTX 时钟要求GTX 调用与控制SMPTE SD/HD/3G-SDISMPTE SD/HD/3G-SDI 接收SMPTE SD/HD/3G-SDI 发送 SDI 视频接收数据处理SDI 音频接收-…

天文观测与计算机技术:共舞在星辰大海

天文观测与计算机技术&#xff1a;共舞在星辰大海 在人类探索宇宙的历程中&#xff0c;天文观测和计算机技术如同一对并肩作战的勇士&#xff0c;共同书写着人类对宇宙的认知。本篇博客将深入探讨这两者如何交织在一起&#xff0c;为人类打开一扇又一扇探索宇宙的窗户。 一、…

羊大师教你如何选择适合孩子的羊奶,孩子成长的关键!

当谈到孩子的健康与成长时&#xff0c;正确的饮食是至关重要的。而在众多的饮品中&#xff0c;羊奶因其独特的营养价值备受家长们的青睐。那么&#xff0c;如何为孩子挑选适合的羊奶成为了一个重要的选择。下面&#xff0c;小编羊大师将为大家介绍如何选择适合孩子的羊奶。 我…

Flask 账号管理列表

Flask 账号管理列表 web/controllers/account/Account.py /index route_account Blueprint( account_page,__name__ )route_account.route( "/index" ) def index():resp_data {}req request.valuespage int( req[p] ) if ( p in req and req[p] ) else 1qu…