(题解)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

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多