(题解)2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) I B J F H

本文主要是介绍(题解)2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) I B J F H,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

I.这是一个签到题哦

原题指路:I-这是一个签到题哦_2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) (nowcoder.com)

题意(1s):

签到题,直接输出"Welcome to GDUTCPC!"就完事了。

代码:

#include<bits/stdc++.h>
using namespace std;void solve() {cout << "Welcome to GDUTCPC!" << endl;
}int main() {solve();return 0;
}

B.Austin Love Math

原题指路:B-Austin Love Math_2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) (nowcoder.com)

题意(1s):

已知 \(f(x) = \frac{x}{\sqrt{x^2 + 1}}\),\(f_{1}(x) = f[f(x)]\),\(f_{n+1}(x) = f[f_n(x)]\), 然后给定\(q(1 \leq q \leq 1e5)\)组\(x\)和\(t\),求每一个\(f_{t}(x)\)的值(注:选手输出与标准输出的相对误差或绝对误差小于\(10^{-4}\)即视为正确)。

思路:

我们推导一下公式找规律。

$$f_{1}(x) =\dfrac{\dfrac{x}{\sqrt{x^2 +1}}}{\sqrt{\dfrac{x^2}{x^2 + 1}+1}} = \frac{x}{\sqrt{2x^2+1}}$$

$$f_{2}(x) =\dfrac{\dfrac{x}{\sqrt{2x^2 +1}}}{\sqrt{\dfrac{x^2}{2x^2 + 1}+1}} = \frac{x}{\sqrt{3x^2+1}}$$

由此我们可以得出规律$$f_n(x) = \frac{x}{\sqrt{(n+1)x^2}+1}$$

代码:

#include<bits/stdc++.h>
using namespace std;void solve() {double x;double t;cin >> x >> t;double ans = (t + 1.0) * x * x + 1.0;double res = x / sqrt(ans);cout << res << endl;
}int main() {CaseTsolve();return 0;
}

J.修棋盘

原题指路:J-修棋盘_2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) (nowcoder.com)

题意(1s):

给定一个\(n\times m (1 \leq n, m \leq 1000)\)大小的棋盘,一开始棋盘染色的时候并没有染成任意相邻两个格子不同颜色的棋盘(用\(0\)来表示当前棋盘格子是白色,\(1\)来表示当前棋盘格子是黑色)。现在找了一个修理工从坐标\((1,1)\)出发,每一次可以往上下左右相邻的格子走一步(不能出棋盘)。然后修理工有两种操作,当走到某个格子用了奇数步的时候,可以把这个格子修理成黑色;偶数步的时候,可以把这个格子修理成白色。修理工最多可以走\(998244353998244353\)步,然后求将棋盘染成任意相邻两个格子颜色不同的棋盘,修理工所需要的最少的操作次数,如果做不到,则输出\(-1\)。

思路:

①:首先我们注意到一个点,就是修理工能够将某个格子染成的颜色是固定的,不会因为修理工是如何走到这个格子而改变,而能染成什么颜色与这个点到原点的曼哈顿距离(两个点在标准坐标系上的绝对轴距总和)有关。假设有一个格子的坐标是\((i,j)\),那么当\(i+j\)是偶数的时候,修理工走到这个格子的步数就是偶数,修理工只能将这个点染成白色(即变成\(0\)),反之当\(i+j\)是奇数的时候,修理工只能将这个点染成黑色(即变成\(1\))

②:除去类似题目样例\(1\)的这种情况 $$\begin{vmatrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 0 & 1  \end{vmatrix}$$ ,也就是\((1,1)\)上是\(1\)并且所有格子已经是满足了任意两个格子相间的情况外,其余的所有的棋盘,只要有一个需要染色的情况,最后一定会染色成 $$\begin{vmatrix} 0 & 1 & 0 \\ 1 & 0 & 1 \\ 0 & 1 & 0  \end{vmatrix}$$这种情况,因为正如上面①所说的那样,某个具体的格子只能染成某种具体的颜色,或者再举个例子,对于下述这种情况$$\begin{vmatrix} 1 & 0 & 1 \\ 0 & 1 & 0 \\ 1 & 1 & 1  \end{vmatrix}$$我们是无法将\((1,2)\)这个格子变成\(0\)的,因为修理工走到这个点的时候一定是奇数步,修理工只能将这个格子变成\(1\),我们能做的只有把其他的格子给全部染掉,最后棋盘一定会变成$$\begin{vmatrix} 0 & 1 & 0 \\ 1 & 0 & 1 \\ 0 & 1 & 0  \end{vmatrix}$$的情况。

③:由于数据给的是\(1 \leq n, m \leq 1000\)的棋盘大小,走“S”型最多只用\(n \times m  \leq 1e6\)步,远远小于\(998244353998244353\),所以是不存在做不到的情况。

(这个数据的唯一作用就是让笔者在做题的时候怀疑人生,看题不走心以为最后要求的是修理工将棋盘染色所需要的最小步数,然后看见榜单别人刷刷刷的过题然后自己做不出来。最后发现求的是最少操作步数,然后开始怀疑自己的眼睛。嘤嘤嘤~)

我们做题的时候只需要判断每个格子的颜色是什么,然后统计与格子原本应该的颜色不同的格子数目,最后输出即可。特别的,当所有格子都不相同,也就是不同的格子的数目等于棋盘上所有的格子的数目的时候,这种情况就是②中的第一个图,所有的格子已经两两相间了,此时不需要再涂色了。

代码:

#include<bits/stdc++.h>
using namespace std;const int N = 1100;string a[N];void solve() {int n, m; cin >> n >> m;for (int i = 0; i < n; i++) {cin >> a[i];}int ans = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (a[i][j] == '1' && (i + j) % 2 == 0) {ans++;}if (a[i][j] == '0' && (i + j) % 2 == 1) {ans++;}}}if (ans == n * m) cout << 0 << endl;else cout << ans << endl;}int main() {solve();return 0;
}

F.魔王大人的打工日常

原题指路:F-魔王大人的打工日常_2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) (nowcoder.com)

题意(1s):

给定\(n\)个盘子,进行\(m\)次操作(\(1 \leq n,m \leq 1e5\))。盘子初始排列是\(P=(1,2,,…,n-1,n)\),每次操作选定第\(l\)个到第\(r\)个碟子进行\(k\)次循环右移(保证\(l \leq r\)且\(k\)在 int 范围内)。(注:对在第\(l\)个到第\(r\)个碟子这个区间的碟子\(P' = (p_l,p_{l+1},,…,p_{r-1},p_r)\)的一次循环操作使得\(P' = (p_r,p_{l},p_{l+1},…,p_{r-1})\),再通俗点讲就是,所有数字往右移一个,最右边的移到最左边去。)然后求出每次操作过后序列中的逆序对(满足\(i < j\)且\(a_i > a_j\))的奇偶性,如果是偶数就输出“hao”,奇数的话就输出“huai”。

思路:

这道题需要用到线性代数的知识,这里只大致引入概念,不作相关证明。如果一个排序(指有\(n\)个互不相同的数,且大小范围都在\(1 \sim n\)之间),他的逆序对的个数恰为偶数,那么我们称这个排序为偶排序,反之如果恰有奇数个逆序对,那么我们称之为奇排序。如果我们将排序中的任意两个数交换位置,那么这个排序的奇偶性改变(也就是交换一次后,奇排序就会变成偶排序,偶排序就会变成奇排序)。

我们知道这个结论之后,就可以开始做题了,假设我们将\(n\)个数进行循环右移,可以视为将最右边的那个数和左边一个的数进行\(n-1\)次交换的操作,也就是奇偶性更改\(n-1\)次。所以我们只需要记录一下,每次操作奇偶性更改的次数,看他更改次数的奇偶性即可。

代码:

#include<bits/stdc++.h>
using namespace std;void solve() {int n, q;cin >> n >> q;int ans = 0;while(q--) {int l, r, t;cin >> l >> r >> t;ans += (r - l) * t;if (ans & 1) cout << "huai" << endl;else cout << "hao" << endl;}}int main() {solve();return 0;
}

H.合成大西瓜

原题指路:H-合成大西瓜_2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) (nowcoder.com)

题意(1s):

有一个垂直管道,上端开口,下端封顶,管道宽度只能放一个球,长度无限,当两个一级球相邻时,就可以变成一个二级球,当两个二级球相邻时,就可以变成一个三级球,当两个三级球相邻时,就可以变成一个四级球。每次操作都会从管道上方随机放入一个一、二或三级球,概率都是三分之一。初始时,管道中有\(n(0 \leq n \leq 1e5)\)个球,然后从下到上依次给出每个球的种类(保证任意相邻的两个球种类不相等),然后求最后管道中合成出四级球的期望次数。

思路:

首先我们应当注意到如果上面的球的级数大于其下方的球的级数,那么下面的球将毫无作用, 因为合成四级球的时候,一定会在上面先和成出四级球,而不会用到下面的小球。因此看似管道中的球能有很多种放法,但都能够归为八种基本状态(两条竖线中夹着的就是小球的种类,下方的字母表示设这种情况最后合成四级球的期望次数)。

\(\begin{Vmatrix}①\end{Vmatrix}\)          \(\begin{Vmatrix}②\end{Vmatrix}\)          \(\begin{Vmatrix}①\\②\end{Vmatrix}\)          \(\begin{Vmatrix}①\\②\\③\end{Vmatrix}\)          \(\begin{Vmatrix}②\\③\end{Vmatrix}\)          \(\begin{Vmatrix}①\\③\end{Vmatrix}\)          \(\begin{Vmatrix}③\end{Vmatrix}\)          \(\begin{Vmatrix}  \end{Vmatrix}\)

   a                  b                 c                  d                  e                  f                  g               h

得出了这八种状态之后(注意,第八种情况比较特殊,容易忘记考虑,就是最开始的时候有可能管道中一个球都没有的情况),我们就可以开始列方程了,我们以第一种状态和第五种状态为例(我认为这两种情况较为典型,举例能相对来说涵盖各种情况方便理解)。

$$a: a = \frac{1}{3}(1 + b) + \frac{1}{3}(1 + b) + \frac{1}{3}(1 + g)$$

有\(\frac{1}{3}\)的概率落下一级球,然后就会合成二级球,变成状态\(2\),因此这一部分的期望是,走上\(1\)步,再加上变成状态\(2\)变成四级球的期望。然后另有\(\frac{1}{3}\)的概率,落下二级球,此时上面的二级球比下面的一级球大,所以下面的一级球就没有用了,因此仍然变成状态\(2\),最后\(\frac{1}{3}\)的概率是落下三级球,此时就变成了状态\(8\)。

$$e: e = \frac{1}{3}(1 + d) + \frac{1}{3}(1 + 0) + \frac{1}{3}(1 + g)$$

对于第五种情况,有\(\frac{1}{3}\)的概率落下一级球,然后就会落在上面,变成状态\(4\),然后另有\(\frac{1}{3}\)的概率,落下二级球,于是两个二级球合成变成三级球,然后两个三级球合成为四级球,完成目标,因此这一部分的期望就是走这一步,最后\(\frac{1}{3}\)的概率是落下三级球,此时这个三级球比他下面的二级球大,于是又变成了状态\(8\)。

最后我们一共可以列出如下八个方程:

$$\begin{cases}a = \frac{1}{3}(1 + b) + \frac{1}{3}(1 + b) + \frac{1}{3}(1 + g)\\b = \frac{1}{3}(1 + c) + \frac{1}{3}(1 + g) + \frac{1}{3}(1 + g)\\c = \frac{1}{3}(1 + g) + \frac{1}{3}(1 + b) + \frac{1}{3}(1 + g)\\d = \frac{1}{3}(1 + 0) + \frac{1}{3}(1 + b) + \frac{1}{3}(1 + g)\\e = \frac{1}{3}(1 + d) + \frac{1}{3}(1 + 0) + \frac{1}{3}(1 + g)\\f = \frac{1}{3}(1 + e) + \frac{1}{3}(1 + b) + \frac{1}{3}(1 + g)\\g = \frac{1}{3}(1 + f) + \frac{1}{3}(1 + e) + \frac{1}{3}(1 + 0)\\h = \frac{1}{3}(1 + a) + \frac{1}{3}(1 + b) + \frac{1}{3}(1 + g)\end{cases}$$

化简后即为:

$$\begin{cases}3a - 2b - g = 3\\3b - c - 2g = 3\\3c - b - 2g = 3\\3d - b - g = 3\\3e - d - g = 3\\3f - b - e - g = 3\\3g - e - f = 3\\3h - a - b - g = 3\end{cases}$$

于是接下来的工作就是解这个八元一次方程组了,首先可以肯定的是,这个方程是一定有解,因为每个状态最后都是可以合成出四级球的,同时这个解一定是唯一解,因为如果存在多组解,那么某一种情况的期望就会出现两个以上,而每种状态最后合成出四级球的概率一定是固定的,不可能存在一会是这个值,一会是那个值的情况。

解这个方程组,一种是可以直接手算硬撕它(反正一定是能解出来的),另一种方法就是高斯消元,这里又要用到线性代数的知识,这也是我最后化简方程将常数项分离放到右边,并且把未知数的系数都变成整数的原因,这样就可以使用高斯消元的板子,来帮我们解出每个未知数的大小了。

高斯消元代码:

#include<bits/stdc++.h>
using namespace std;//高斯消元
//枚举每一列的C
// ① 找到绝对值最大的一行 (为了防止精度丢失)
// ② 将该行换到最上面
// ③ 将该行第一个数变成1
// ④ 将下面所有行的第C列清成0const int N = 110;
const double eps = 1e-8;
int n;
double a[N][N];int gauss() {int c, r;for (c = 0, r = 0; c < n; c++) { //枚举每一列,找到绝对值最大的这一行int t = r;for (int i = r; i < n; i++) { //找到绝对值最大的这一行是哪一行if (fabs(a[i][c]) > fabs(a[t][c])) t = i;}if (fabs(a[t][c]) < eps) continue; //如果是零的话,就不用操作了for (int i = c; i <= n; i++) swap(a[t][i], a[r][i]); //交换,把绝对值最大的一行换到上面for (int i = n; i >= c; i--) a[r][i] /= a[r][c]; //把第一个数变成1.后面的数跟着变,当然第一个数要最后一个更新成1for (int i = r + 1; i < n; i++) {if (fabs(a[i][c]) > eps) {for (int j = n; j >= c; j--) {a[i][j] -= a[r][j] * a[i][c];}}}r++;}if (r < n) {for (int i = r; i < n; i++) {if (fabs(a[i][n]) > eps) {return 2;}}return 1;}for (int i = n - 1; i >= 0; i--) {for (int j = i + 1; j < n; j++) {a[i][n] -= a[i][j] * a[j][n];}}return 0;
}void solve() {cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j < n + 1; j++) {cin >> a[i][j];}}int t = gauss();if (t == 0) {for (int i = 0; i < n; i++) {if (fabs(a[i][n]) < eps) a[i][n] = 0;printf("%.8lf\n", a[i][n]);}}else if (t == 1) cout << "Infinite group solutions" << endl;else cout << "No solution" << endl;}int main() {solve();return 0;
}

高斯消元输入和输出:

我们在把每个未知数都求出来后,也就算出来了每种情况的期望合成次数,因此我们可以将打出来的表写在另外一篇代码中,然后在这篇代码中判断初始时管道中的球是什么情况。

最终(你要交上去的)代码:

代码中的\(flag\)表示的是第几种情况。写到这里的时候我已经有点神志不清了,所以就直接暴力到底了,反正都打表了,所以是直接判断管道中的球是零个、一个、两个、三个以上,以及各自可能存在的情况,暴力 else-if 语句去判断管道中的球的初始状态了。

#include<bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;
int a[N];void solve() {int n; cin >> n;int flag = 0;if (n == 0) {flag = 8;}for (int i = 1; i <= n; i++) {cin >> a[i];}if (n == 1) {if (a[1] == 1) {flag = 1;}if (a[1] == 2) {flag = 2;}if (a[1] == 3) {flag = 7;}}if (n == 2) {if (a[2] == 3) {flag = 7;}if (a[2] == 2 && a[1] == 3) {flag = 5;}if (a[2] == 2 && a[2] == 1) {flag = 2;}if (a[2] == 1 && a[1] == 2) {flag = 3;}if (a[2] == 1 && a[1] == 3) {flag = 6;}}if (n >= 3) {if (a[n] == 3) {flag = 7;}if (a[n] == 2 && a[n - 1] == 1) {flag = 2;}if (a[n] == 2 && a[n - 1] == 3) {flag = 5;}if (a[n] == 1 && a[n - 1] == 3) {flag = 6;}if (a[n] == 1 && a[n - 1] == 2) {if (a[n - 2] == 3) {flag = 4;}if (a[n - 2] == 1) {flag = 3;}}}double f[9] = {0.0, 6.08139535, 5.58139535, 5.58139535, 4.22093023, 3.76744186, 5.47674419, 4.08139535, 6.24806202};printf("%.8lf\n", f[flag]);}int main() {solve();return 0;
}


这篇关于(题解)2023年“华为”杯广东工业大学第十七届程序设计竞赛(同步赛) I B J F H的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/341475

相关文章

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

华为鸿蒙HarmonyOS 5.1官宣7月开启升级! 首批支持名单公布

《华为鸿蒙HarmonyOS5.1官宣7月开启升级!首批支持名单公布》在刚刚结束的华为Pura80系列及全场景新品发布会上,除了众多新品的发布,还有一个消息也点燃了所有鸿蒙用户的期待,那就是Ha... 在今日的华为 Pura 80 系列及全场景新品发布会上,华为宣布鸿蒙 HarmonyOS 5.1 将于 7

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

Mac备忘录怎么导出/备份和云同步? Mac备忘录使用技巧

《Mac备忘录怎么导出/备份和云同步?Mac备忘录使用技巧》备忘录作为iOS里简单而又不可或缺的一个系统应用,上手容易,可以满足我们日常生活中各种记录的需求,今天我们就来看看Mac备忘录的导出、... 「备忘录」是 MAC 上的一款常用应用,它可以帮助我们捕捉灵感、记录待办事项或保存重要信息。为了便于在不同

查看MySql主从同步的偏移量方式

《查看MySql主从同步的偏移量方式》:本文主要介绍查看MySql主从同步的偏移量方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 1.mysql的主从同步方案mysqlphp为了在实现读写分离,主库写,从库读mysql的同步方案主要是通过从库读取主库的binl

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Linux搭建Mysql主从同步的教程

《Linux搭建Mysql主从同步的教程》:本文主要介绍Linux搭建Mysql主从同步的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux搭建mysql主从同步1.启动mysql服务2.修改Mysql主库配置文件/etc/my.cnf3.重启主库my