Acwing枚举、模拟与排序(二)

回文日期

原文链接:https://www.acwing.com/problem/content/468/

由于只有八位数,而且回文串左右对称,因此可以只枚举左半边。然后判断:

  • 整个八位数日期是否合法
  • 是否在范围内

一共枚举1e4个数。判断过程是常数级别的,所以总计算量是 O ( 1 0 4 ) O(10^4) O(104)
代码中的check属于基操。

#include"bits/stdc++.h"using namespace std;
int date1, date2;
int months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};bool check(int date) {int year = date / 10000;int month = date % 10000 / 100;int day = date % 100;if (!month || month >= 13 || !day) return false;if (month != 2 && day > months[month]) return false;if (month == 2) {bool leap = year % 4 == 0 && year % 100 || year % 400 == 0;if (day > 28 + leap) return false;}return true;
}int main() {int res = 0;cin >> date1 >> date2;for (int i = date1 / 1e4; i < date2 / 1e4; i++) {int date = i, tmp = i;for (int j = 0; j < 4; j++)date = date * 10 + tmp % 10, tmp /= 10;if (date >= date1 && date <= date2 && check(date))res++;}cout << res << endl;return 0;
}

参考

  • https://www.acwing.com/solution/content/3897/

日期问题

原题链接:https://www.acwing.com/problem/content/1231/

真就是在枚举。

#include"bits/stdc++.h"using namespace std;int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int check(int year, int month, int day) {if (month > 12 || month < 1)return false;if (day == 0)return false;if (month != 2) {if (day > days[month])return false;} else {int leap = year % 4 == 0 && year % 100 || year % 400 == 0;if (day > 28 + leap)return false;}return true;
}int a, b, c;int main() {scanf("%d/%d/%d", &a, &b, &c);for (int date = 19600101; date <= 20591231; date++) {int year = date / 10000, month = date / 100 % 100, day = date % 100;if (check(year, month, day)) {if (year % 100 == a && month == b && day == c ||month == a && day == b && year % 100 == c ||day == a && month == b && year % 100 == c) {printf("%d-%02d-%02d\n", year, month, day);}}}return 0;
}

航班时间

原题链接:https://www.acwing.com/problem/content/1233/

不知道时差是多少,要求真实的飞行时间。
去的时候,从东向西,减时差:

  • 飞行时间=起降时间之差-时差

回的时候,从西向东,加时差:

  • 飞行时间=起降时间之差+时差

两式作和,然后除以二,就可以求出飞行时间。

  1. 将所有时间转换成距离当天00:00:00的秒数。
  2. 按行读入,对于行末可能有也可能没有的(),格式化统一处理。

cinscanf都不会干掉第一行的回车。
在这些函数执行完成之后,执行getline之前,多执行一次getline:去掉回车。

#include"bits/stdc++.h"using namespace std;int t;int getSecond(int h, int m, int s) {return h * 3600 + m * 60 + s;
}int getTime() {string line;getline(cin, line);if (line.back() != ')')line += " (+0)";for (int i = 0; i < 2; i++) {int h1, m1, s1, h2, m2, s2, d;sscanf(line.c_str(), "%d:%d:%d %d:%d:%d (+%d)", &h1, &m1, &s1, &h2, &m2, &s2, &d);return getSecond(h2, m2, s2) - getSecond(h1, m1, s1) + d * 24 * 3600;}
}int main() {cin >> t;//忽略第一行的回车string line;getline(cin, line);while (t--) {int time = (getTime() + getTime()) >> 1;int hour = time / 3600, minute = time % 3600 / 60, second = time % 60;printf("%02d:%02d:%02d\n", hour, minute, second);}return 0;
}

外卖店优先级

原题链接:https://www.acwing.com/problem/content/1243/

数据量为1e5,如果按时间顺序枚举每一份订单,很有可能超时。
在整个过程中,有一部分时间是没有订单的,这一部分就可以暂时跳过。
等到有订单的时候再来处理。
这样,只有在有订单的时间点才去处理数据,而非遍历从头到尾的每个时刻。减少数据量。
这就需要:在枚举之前,先对订单数组按时间排序。
然后,按时间顺序遍历订单。
遍历每个订单时,查看上一次该店铺收到订单的时间。存储该时间需要创建一个数组,店铺号作为下标,值为上一次的订单时间。

  1. 先减去时间差,统一处理之前的无订单事件。
  2. 再提高优先级,处理订单事件。

如果当前店铺的最后一个订单不在最后一个时刻。那么遍历订单的时候,不会再遍历到该店铺,不会进入上面两步,处理该店铺的无订单事件,但是这期间,该店铺的优先级在持续降低。
解决方案就是,在最后一个时刻,遍历所有店铺上一次订单的时间。统一处理无订单事件。

#include"bits/stdc++.h"using namespace std;#define x first
#define y second
typedef pair<int, int> PII;
int n, m, T;
PII order[100010];
int score[100010], last[100010], st[100010];int main() {cin >> 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;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 = 0; i <= n; i++)res += st[i];cout << res << endl;return 0;
}

上面的代码中,比较费解的是:

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;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;
}

order是一个pair二元组,.first.second的值分别是时间和店铺。
while()的结束条件是:

  • j已经移动到了数组边界之外。
  • order订单二元组不完全相等。

这是因为同一时刻,可能有多个指向同一店铺的订单,同无订单事件一样。也可以集中处理。
这个循环的作用,就是统计相同的订单的数量。相同订单的条件是,时间和店铺相同。
每个订单都会提供2点优先级,因此后面的代码中有score[id] += cnt * 2;
所以,上面这段代码的作用是:

  1. 枚举每一个订单。(枚举之前已经排序)
  2. 对于当前订单,相同的订单的数量,并将指针移动到下一个不同的订单。
  3. 处理当前订单指向的店铺,之前的“无订单”事件。
  4. 处理当前订单指向的店铺,当前的“有订单”事件。
  5. 更新last数组,存储的是,当前订单指向的店铺,的上一次订单时刻。

逆序对的数量

原题链接:https://www.acwing.com/problem/content/790/

归并排序:

  1. [L,R]=>[L,mid],[mid+1,R]
  2. 递归排序[L,mid]和[mid+1,R]
  3. 归并,将左右两个有序序列合并成一个有序序列

以mid为分界点,逆序对的两个数可能同时出现在左半边,也可能同时出现在右半边,也可能一个在左一个在右。
各区间内的逆序对数量:

  • 左半边内部的逆序对数量:merge_sort(L,mid)
  • 右半边内部的逆序对数量:merge_sort(mid+1,R)

一个在左一个在右的情况:
在左半部分和右半部分时,假设已经排好序了,并且返回了所在区间的逆序对数量。
对左半部分和右半部分继续归并排序,左区间指针大于右区间指针时,由于左右区间已经分别排好序了,那么左区间指针右侧的值都大于右区间指针当前指向的值,左区间的较大值都可以与右区间当前值构成逆序对。符合要求的取值的数量就等于mid-i+1
也就是用两个指针,每次发现右侧有较小值时,答案加上mid-i+1
当一侧指针指到结束位置的时候,扫尾。扫尾的时候不需要修改答案。

#include"bits/stdc++.h"using namespace std;typedef long long LL;
int q[100010], tmp[100010];
int n;LL merge_sort(int l, int r) {if (l >= r)return 0;int mid = l + r >> 1;LL res = merge_sort(l, mid) + merge_sort(mid + 1, r);int k = 0, i = l, j = mid + 1;while (i <= mid && j <= r)if (q[i] <= q[j])tmp[k++] = q[i++];else {tmp[k++] = q[j++];res += mid - i + 1;}while (i <= mid)tmp[k++] = q[i++];while (j <= r)tmp[k++] = q[j++];for (int i = l, j = 0; i <= r; i++, j++)q[i] = tmp[j];return res;
}int main() {cin >> n;for (int i = 0; i < n; i++)cin >> q[i];cout << merge_sort(0, n - 1) << endl;return 0;
}

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

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

相关文章

CC攻击的特征和防护措施

随着互联网的快速发展&#xff0c;网络攻击日益频繁。在目前的各种网络攻击中&#xff0c;CC攻击是一种常见的网络攻击手段之一。CC攻击&#xff08;也称为DDoS攻击&#xff09;是指通过大量请求或恶意流量向目标网站或服务器发送请求&#xff0c;以使其服务不可用。可能大家都…

Error:java:JDK isn‘t specified for module “模块名称“

可能是创建模块后不小心删掉了.idea.或.idea出错 只要删除.idea&#xff0c;close project出去&#xff0c;重新进让idea自动下载

VS2022打包C#安装包(最新、最全)

开发c#的一个小工具到打包环境碰壁了&#xff0c;在网上找了很多资料耶踩了很多坑&#xff0c;耗时1hour才打包完毕&#xff0c;避免以后碰到类似的问题再次记录&#xff0c;自认为步骤比较全面&#xff0c;如果有帮助麻烦点个赞呗&#xff01;&#xff01;&#xff01; 一、Mi…

QT状态机入门

Qt状态机&#xff08;QStateMachine&#xff09;是Qt框架中用于管理状态和状态转换的一种工具。它允许您将程序的行为分解为一系列离散的状态&#xff0c;并根据一定的条件进行状态之间的转换。Qt状态机提供了一个灵活的、可视化的方式来描述程序的状态和状态转换关系。 优点&…

网易家居315特别策划 | MLILY梦百合荣获2024年度家居行业服务榜样

3月,网易家居“寻找家居服务榜样”315特别策划如期而至,重磅奖项“2024年度家居行业服务榜样”揭晓,该奖项授予在家居服务方面做出突出贡献、起到示范引领作用的先进企业。其中,MLILY梦百合荣获“2024年度家居行业服务榜样”重磅奖项。 伴随市场需求演变、企业发展驱动、产业升…

echarts使用总结

最近项目大量的曲线图,柱状图,饼图...总结一下使用过程中的小问题及解决方法 . 1.当x轴太拥挤,x轴数据不能全部展示怎么办? 这时候就只需要在xAxis的axisLabel对象中添加属性 interval : 0 就可以显示全部数据 , interval 属性是用来调整x轴数据的间距的 , 数值越大间距越大…

Linux基础命令[11]-find

文章目录 1. find 命令说明2. find 命令语法3. find 命令示例3.1 不加参数3.2 按照时间3.3 -empty&#xff08;空白文件或目录&#xff09;3.4 -name&#xff08;名称查找&#xff09;3.5 -size&#xff08;大小查找&#xff09;3.6 -type&#xff08;类型查找&#xff09;3.7 …

砝码称重 蓝桥杯

在C中&#xff0c;fabs()和abs()都用于计算数字的绝对值&#xff0c;但它们之间有一些区别。 fabs(double x)&#xff1a;计算浮点数x的绝对值&#xff0c;返回一个double类型的结果。 abs(int x)&#xff1a;计算整数x的绝对值&#xff0c;返回一个int类型的结果。 数组的默…

1w字带你快速入门Docker

1. 什么是容器 容器是一种轻量级的、可移植的、自包含的软件单元&#xff0c;它包含运行应用程序所需的所有内容&#xff0c;包括代码、运行时、系统工具、系统库和设置。容器与虚拟机类似&#xff0c;但它们更加轻量级&#xff0c;并且依赖于宿主内核。容器可以使用 Docker 等…

太阳能光伏电池的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 光伏电池的基本结构 4.2 光伏电池的工作原理 5.完整工程文件 1.课题概述 太阳能光伏电池的simulink建模与仿真.分析不同光照温度&#xff0c;光照强度下的光伏电池的U-I特性曲线以及P-V特性曲线。 …

缺一不可!私域运营的三大核心环节

众所周知&#xff0c;私域运营是现如今许多企业重要的发展策略之一&#xff0c;通过建立和管理自己的用户数据库&#xff0c;实现用户粘性和价值的提升。 那么&#xff0c;要想做好私域运营&#xff0c;这三大核心环节一个也不能少&#xff01; 内容运营 内容运营是私域运营…

应用服务器和Web服务器的关系?

应用服务器实现了JavaEE的所有规范。&#xff08;JavaEE有13个不同的规范&#xff09;Web服务器只实现了JavaEE中的ServletJSP两个核心的规范应用服务器是包含WEB服务器的 apache官网地址&#xff1a;https://www.apache.org/ tomcat官网地址&#xff1a;https://tomcat.apach…

java VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城 小程序商城搭建

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

php安装kafka

我的开发环境是php7.3 ,先来部署两个php扩展&#xff0c;php7.3目录下放librdkafka.dll,ext/php_rdkafka.dll&#xff0c;php.ini增加,[rdkafka] extension php_rdkafka.dll php7.3对应的扩展包链接&#xff1a;PECL :: Package :: rdkafka 看自己php版本对应在这里找PECL :: …

OpenAI-Sora学习手册

通过Sora看2024红利&#xff1a;文生视频&#xff0c;虽然AI不一定是风口&#xff0c;但一定是未来深入到生活工作&#xff0c;乃至思考的必备工具。 目录 Sora介绍 Sora基础介绍 Sora官方网址 Sora的价值 1.物理世界的交互 2.创意世界的绽放 3.多角色、更精准、更细节…

Vue时间轴

之前有这样子的需求没有用第三方插件于是自己写一个简单的时间轴 时间轴滚动条并左右切换滚动条位置相对应移动 <div class"time-scrollbar"><div v-if"timeLineData.length>0" class"scrollbar-content"><div class"ar…

SAP PP学习笔记07 - 简单BOM,派生BOM,多重BOM,批量修改工具 CEWB

上一章讲了BOM的操作。 SAP PP学习笔记06 - BOM操作&#xff08;BOM 展开&#xff0c;BOM 使用先一览&#xff0c;BOM比较&#xff0c;批量更改BOM&#xff09;-CSDN博客 本章延续上一章&#xff0c;继续讲BOM操作。 主要讲 派生BOM&#xff0c;多重BOM&#xff0c;以及BOM批…

收费的Excel,不收费的国产WPS、Ever这4款加强版,谁口碑更好?

国产软件存在的问题不在少数&#xff0c;诸如“流氓捆绑”、“广告弹屏”、“APP乱象”、“大数据杀熟”等弊端&#xff0c;让许多人对其嗤之以鼻。 尽管国内软件往往免费&#xff0c;而国外软件需要付费&#xff0c;大家还是更愿意选择付费使用国外软件&#xff0c;并且许多国…

java修改static final String常量值

java修改static final String常量值 背景 在项目中使用的JPA&#xff0c;Table设置实体类表名&#xff0c;使用mysql数据库的话&#xff0c;设置Table中catalog和schema可以在生成查询sql时&#xff0c;加上schema。例如表为sys_node&#xff0c;库名叫stu_manage&#xff0c…

Selenium自动化测试-3.元素定位(1)

这次我们要分享的是对元素的定位&#xff0c;在一个页面中有很多不同的策略来定位一个元素&#xff0c;我们选择最合适的方法即可。 一个页面最基本组成单元是元素&#xff0c;想要定位一个元素&#xff0c;我们需要特定的信息来说明这个元素的唯一特征。 selenium 主要提供了…