西安石油大学2023年第三届里奇杯编程大赛(初赛)

这篇具有很好参考价值的文章主要介绍了西安石油大学2023年第三届里奇杯编程大赛(初赛)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

官方题解地址1v7w (郭毅佬!):https://www.cnblogs.com/1v7w/p/17437203.html

A 签到

描述

你说得对,但是 “ 里奇杯 ” 是西安石油大学计算机协会举办的程序设计竞赛,比赛旨在激发同学们学习程序设计的热情,提高编程能力,调动编程的兴趣和积极性,在这里,你将扮演名为“参赛选手”的神秘角色,展示分析问题、解决问题和动手编程的能力,培养创新思维,开拓视野,邂逅志趣相投的同伴,同时,逐步发掘 “ 算法 ” 的魅力。

输入

无

输出

输出一行字符串Hello Liqi contest


输入样例 1     无
输出样例 1     Hello Liqi contest
#include <bits/stdc++.h>
using namespace std;
 
int main()
{
 cout << "Hello Liqi contest";
 return 0;
}

其他方法(推荐去leetcode或者洛谷去看各路神仙的输出方法,直接劝退萌新doge)


以下是几种在C++中输出"Hello Liqi contest"的方法:

1. 使用cout语句:
```
#include <iostream>

using namespace std;

int main() {
    cout << "Hello Liqi contest" << endl;
    return 0;
}
```

2. 使用printf语句:
```
#include <stdio.h>

int main() {
    printf("Hello Liqi contest\n");
    return 0;
}
```

3. 使用puts语句:
```
#include <stdio.h>

int main() {
    puts("Hello Liqi contest");
    return 0;
}
```

4. 将字符串存储到变量中,再使用cout语句输出:
```
#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "Hello Liqi contest";
    cout << str << endl;
    return 0;
}
```

B 挂科

描述

老师希望同学们都能取得一个好成绩,所以每次成绩出来,老师去统计一下有多少同学挂科了。现在老师安排让1v7w去统计,但他数数不太行,请你给写个程序帮他统计一下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6SszeRBt-1687177451108)(2023-06-04-21-00-48.png)]
分析思路
在这个示例中,我们先定义三个变量,分别表示学生数量、及格线和学生成绩数组。然后使用scanf函数从标准输入中读取n和p的值,再使用for循环读取n个学生的成绩到数组a中。

最后,使用一个for循环遍历所有学生成绩,输出及格的学生成绩。

#include <stdio.h>
int main() 
{
   int n, p, a[105];
   scanf("%d%d", &n, &p);
   for (int i = 0; i < n; i++) {
      scanf("%d", &a[i]);
   }

   // 输出所有及格学生的成绩
   printf("及格的学生成绩:");
   for (int i=0;i<n;i++){
      if (a[i] >= p) {
         printf("%d ", a[i]);
      }
   }
   printf("\n");
   return 0;
}

官方题解:

//这段代码实现了统计成绩低于及格线的学生数量。
//首先,我们定义了一个常量N表示数组a的最大长度。
//然后,使用scanf函数从标准输入中读取n和p的值,
//并使用for循环遍历n个学生的成绩,并把它们存储在数组a中。
//接下来,我们定义一个变量res,用于记录成绩低于及格线的学生数量。
//使用一个循环遍历数组a,如果某个学生成绩小于及格线,则将res的值加一。

最后,输出成绩低于及格线的学生数量res即可。
#include <iostream>
#include <algorithm>
 
using namespace std;
 
const int N =  1e5+10;
int n, p, a[N], res;
 
int main() {
    scanf("%d%d", &n, &p);
    for(int i=1; i<=n; i++) {
        scanf("%d", &a[i]);
        if(a[i] < p) res++;
    }
    printf("%d\n", res);
    return 0;
}

C 送外卖

暑假1v7w想要赚钱,于是就进入了美团大厂,成为了一名骑手。

这一天他抢到了 n 个订单,这些订单的目的地都在宝鸡钢管路上(可以看做在一条坐标轴上),第 i 个订单的目的地的位置是 。

帮1v7w找一下,他最少走多长的距离就能够把外卖全部送完?这里他可以从任意一点开始送外卖,并从任意一点结束送外卖。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ErPiyk80-1687177451111)(2023-06-04-21-15-21.png)]

经过论证,可以发现,沿着坐标轴,从左到右一口气送完外卖是最佳方案。故将求出 a的最大值与最小值后直接相减即可。
官方题解:
这段代码实现了求取n个数中最大值和最小值的差。

在main函数中,我们首先使用scanf函数读取变量n的值。接着,我们定义了两个变量minv和maxv,分别表示当前遍历到数列中出现的最小值和最大值(初始值需要设得足够大或小)。使用一个循环遍历输入的n个数,更新minv和maxv的值。最后,输出maxv和minv的差就是答案。

在代码中还有一部分注释掉了,这部分代码是用于多组数据的处理。如果输入有多组数据,需要将其放在while(t–)循环内部来解决。

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
 
#define fi first
#define se second
 
using namespace std;
using ll = long long;
using pii = pair<int, int>;
 
const double eps = 1e-4;
const int N = 110;
int n;
 
void solve() {
    scanf("%d", &n);
    int minv = 1e9, maxv = 0;
    for(int i=1; i<=n; i++) {
        int x; scanf("%d", &x);
        minv = min(minv, x);
        maxv = max(maxv, x);
    }
    printf("%d\n", maxv-minv);
}
 
int main() {
    // multiple case
    // int t; scanf("%d", &t);
    // while(t--) {
    //     solve();
    // }
 
    // single case
    solve();
 
    return 0;
}

经过论证,可以发现,沿着坐标轴,从左到右一口气送完外卖是最佳方案。故将求出 a的最大值与最小值后直接相减即可。

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;
int n, a[N];

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    int maxv = *max_element(a, a + n);   // 求数组a中的最大值
    int minv = *min_element(a, a + n);   // 求数组a中的最小值

    cout << maxv - minv << endl;   // 输出最大值与最小值的差

    return 0;
}

首先,使用cin从标准输入中读取变量n的值,并用一个for循环遍历将后面n个数读入数组a中。

然后,使用STL库函数*max_element*min_element分别求得a中的最大值和最小值,并依次赋值给maxv和minv。

最后,输出maxv和minv的差就是答案。

D 分弹珠

描述

你和你的好朋友在放学的路上捡到了N颗弹珠(每颗弹珠都是一模一样的),看到四下无人,你们俩打算将这些弹珠分掉,请问在确保每个人都能分到的情况下共有多少种分配方式?

输入
第一行包含一个整数 1≤ ≤15

N(1≤N≤15),表示弹珠的总数。

输出

输出一个整数,表示分配方式的总数。

官方题解

每个弹珠都一模一样,故弹珠分配方案的不同只有每个人分的的弹珠多少。

每个人能分得的弹珠数量区间是 [1,n−1] ,故方案数为 n−1。这里直接把弹珠数量为 1的情况(没有合理的分配方案)也涵盖了。

#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
	cin >> n;
	cout << n - 1;
	return 0;
}

E.加倍整数

描述

我们将一个位数为偶数且前半部分与后半部分相同的数称为加倍整数,例如:
11

1212

123123
11,1212,123123 等。

给你一个整数 N ,请问从 1 到 N 有多少个加倍整数?

输入
第一行包含一个整数 1 <= N <= 10^12

输出
输出一行,表示加倍整数的个数。

官方题解

比起判断某个数是否为加倍整数,不如直接构造加倍整数出来,判断他与 n的关系。

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
 
#define fi first
#define se second
 
using namespace std;
using ll = long long;
using pii = pair<int, int>;
 
const double eps = 1e-4;
const int N = 1e6+10;
ll n;
 
// 将x变为xx的加倍整数
inline ll bianshen(ll x) {
    string s = to_string(x);
    s = s + s;
    return stoll(s);
}
 
void solve() {
    cin >> n;
    ll res = 0;
    for(ll i = 1; i < N; i++) {
        ll x = bianshen(i);
        if(x <= n) res++;
    }
    cout << res << endl;
}
 
int main() {
    // multiple case
    // int t; scanf("%d", &t);
    // while(t--) {
    //     solve();
    // }
 
    // single case
    solve();
 
    return 0;
}

这段代码实现了一个简单的功能:计算小于等于n的加倍整数的个数。
代码中首先定义了常量N为1e6+10,并定义了变量n和函数bianshen(x)。函数bianshen(x)用于将x变为xx的加倍整数,即将x的字符串形式重复一次后再转为整数。
在主函数中,首先读入n的值,然后使用for循环遍历所有小于N的正整数i,计算i的加倍整数bianshen(i)。如果bianshen(i)小于等于n,则将计数器res加1。
最后输出res的值,即小于等于n的加倍整数的数量。
该代码使用了C++11的标准库,包括iostream、algorithm、queue、set、map、vector、string等头文件,以及using关键字定义了ll和pii等类型别名,方便了代码编写。代码的时间复杂度为O(NlogN),其中N为1e6,可通过本题。

个人题解

加倍整数指的是一个正整数,如果将它的最高位复制一次接在它的最低位之后,得到的新数是原数的两倍。例如,22是一个加倍整数,因为它的最高位是2,将2复制一次得到新数122,而122是22的两倍。
以下是一段C++代码,可用于判断一个正整数是否为加倍整数:


#include <iostream>
#include <cstring>
using namespace std;
bool isDouble(int n)
{
    bool flag = false;
    string str = to_string(n); // 将整数转为字符串
    int len = str.length();
    if (str[0] == str[len-1])  // 判断最高位和最低位是否相等
    {
        flag = true;
        for (int i = 1; i < len/2; i++)  // 判断其他位是否相等
        {
            if (str[i] != str[i+len/2])
            {
                flag = false;
                break;
            }
        }
    }
    return flag;
}
int main()
{
    int n;
    cout << "请输入一个正整数:";
    cin >> n;
    if (isDouble(n))
        cout << n << "是加倍整数。" << endl;
    else
        cout << n << "不是加倍整数。" << endl;
    return 0;
}

该代码首先将输入的正整数转换为字符串,然后判断最高位和最低位是否相等,如果相等再判断其他位是否相等,最后返回判断结果。

大学生特种兵

西安石油大学2023年第三届里奇杯编程大赛(初赛)

官方题解

假如有一段路程为 1−>2−>4−>5−>3,则他旅行的起点可以为其中的任意一个,终点为起点后的任意一个。故我们可以枚举起点,然后搜索他能够去到哪些终点。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
 
using namespace std;
const int N = 2010;
int n, m, st[N];
vector<int> e[N];
 
// 任何dfs的u都可能为终点
void dfs(int u, int &sum) {
    st[u] = true;
    sum++;
    for(auto ne:e[u]) {
        if(st[ne]) continue;
        dfs(ne, sum);
    }
}
 
int main() {
    scanf("%d%d", &n, &m);
    for(int i=1; i<=m; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        e[a].push_back(b);
    }
    int res = 0;
    for(int i=1; i<=n; i++) {
        memset(st, 0, sizeof(st));
		// 这里的表示起点为i
        dfs(i, res);
    }
    printf("%d\n", res);
    return 0;
}

DFS

DFS(Depth First Search)即深度优先搜索,是一种常见的图遍历算法。在C++中,可以使用递归或栈来实现DFS算法。
具体实现方式如下:

  1. 递归
    递归实现DFS算法比较简单,代码如下:
const int N = 100010;
vector<int> g[N]; // 图的邻接表表示
bool vis[N]; // 记录每个节点是否被访问过
// 从节点u开始进行深度优先遍历
void dfs(int u) {
    vis[u] = true; // 标记节点u为已访问
    cout << u << " "; // 输出节点u
    for (auto v : g[u]) { // 遍历节点u的出边
        if (!vis[v]) { // 如果节点v未被访问过
            dfs(v); // 递归遍历节点v
        }
    }
}
int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1); // 从节点1开始进行深度优先遍历
    return 0;
}

在这段代码中,dfs函数代表从节点u开始进行深度优先遍历。首先标记节点u为已访问,然后输出节点u,最后遍历节点u的所有出边。如果一个出边指向的节点v未被访问过,则递归调用dfs(v)进行遍历。
2. 栈
非递归实现DFS算法需要手动维护一个栈来存储节点信息,代码如下:

const int N = 100010;
vector<int> g[N]; // 图的邻接表表示
bool vis[N]; // 记录每个节点是否被访问过
// 从节点u开始进行深度优先遍历
void dfs(int u) {
    stack<int> stk; // 定义一个栈
    stk.push(u); // 将起始节点u入栈
    while (!stk.empty()) { // 当栈不为空时
        int t = stk.top();
        stk.pop();
        if (!vis[t]) { // 如果节点t未被访问过
            vis[t] = true; // 标记节点t为已访问
            cout << t << " "; // 输出节点t
            for (auto v : g[t]) { // 遍历节点t的出边
                if (!vis[v]) { // 如果节点v未被访问过
                    stk.push(v); // 将节点v入栈
                }
            }
        }
    }
}
int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1); // 从节点1开始进行深度优先遍历
    return 0;
}

在这段代码中,dfs函数代表从节点u开始进行深度优先遍历。我们使用一个栈来存储节点信息,将起始节点u入栈。当栈不为空时,取出栈顶节点t。如果节点t未被访问过,则标记节点t为已访问,输出节点t,遍历节点t的所有出边,将出边指向的未访问节点v入栈。

总结一下,DFS算法是一种非常常用的图遍历算法,递归实现简单,但是当图过大时有可能导致栈溢出。因此,我们可以使用非递归方法,手动维护一个栈来实现DFS遍历。在使用DFS遍历图时,要注意记录每个节点是否被访问过,避免重复访问。

不许6

西安石油大学2023年第三届里奇杯编程大赛(初赛)

官方题解

a=[1,2,3,4,5,7,8,9,10,11,12,13,14,15,17,18,…]。从这里可以发现这个数字世界就是一个使用数字 0,1,2,3,4,5,7,8,9的九进制。故我们将获取到的数字从十进制转换为九进制即可,注意把转换后的 [6,8]变为 [7,9]。

#include <iostream>
#include <algorithm>
#include <vector>
 
using namespace std;
using ll = long long;
 
void solve() {
    ll k; scanf("%lld", &k);
    vector<ll> res;
    while(k) {
        res.push_back(k%9);
        k /= 9;
    }
    reverse(res.begin(), res.end());
    for(auto &x:res) {
        if(x >= 6) x++;
        printf("%lld", x);
    }
    puts("");
}
 
int main() {
    int t; scanf("%d", &t);
    while(t--) {
        solve();
    }
    return 0;
}

根据题目描述,1v7w的数字世界中没有数字6,因此我们需要将所有数字中的6去掉,生成新的数字序列。
具体代码实现如下:

#include <iostream>
#include <vector>
using namespace std;
vector<int> a;
void generate() {
    int x = 1;
    while (x <= 1000000) {
        if (x % 10 != 6 && x / 10 % 10 != 6) {
            a.push_back(x);
        }
        x++;
    }
}
int main() {
    generate();
    int k;
    cin >> k;
    if (k <= 0 || k > a.size()) {
        cout << "Error" << endl;
    } else {
        cout << a[k - 1] << endl;
    }
    return 0;
}

首先,我们定义一个vector a来存储符合要求的数字序列,然后编写generate函数来生成这个序列。generate函数使用一个while循环来遍历所有小于等于1000000的正整数,将没有6的数字加入到a中。

在主函数中,我们读入一个整数k,判断其是否在a的下标范围之内。如果在范围之内,则输出a[k-1],即第k个符合要求的数字;否则输出"Error"。

该程序的时间复杂度是O(n),其中n是符合要求的数字个数,即小于等于1000000的去掉了含有数字6的数字个数,可以通过本题。

vector

在C++中,vector是一个非常常用的动态数组容器,它可以在运行时动态扩展大小,并且支持随机访问、在尾部添加元素、在尾部删除元素等操作。在使用vector时,需要包含头文件。
vector的定义方式如下:

vector<int> v; // 定义一个空的vector容器
vector<int> v(n); // 定义一个有n个元素的vector容器,每个元素都是0
vector<int> v(n, m); // 定义一个有n个元素的vector容器,每个元素都是m

其中,n表示vector容器的大小,m表示初始值。可以通过v.size()来获取vector容器的大小,通过v[i]来访问第i个元素。
vector的常用操作如下:

  1. 在尾部添加元素
vector<int> v;
v.push_back(1); // 在尾部添加元素1
v.push_back(2); // 在尾部添加元素2
  1. 在尾部删除元素
vector<int> v = {1, 2, 3};
v.pop_back(); // 删除尾部元素3
v.pop_back(); // 删除尾部元素2
  1. 随机访问元素
vector<int> v = {1, 2, 3};
cout << v[0] << endl; // 输出第一个元素1
cout << v[1] << endl; // 输出第二个元素2
cout << v[2] << endl; // 输出第三个元素3
  1. 清空vector
vector<int> v = {1, 2, 3};
v.clear(); // 清空vector
  1. 遍历vector
vector<int> v = {1, 2, 3};
for (int i = 0; i < v.size(); i++) {
    cout << v[i] << " ";
}
cout << endl;
  1. 插入元素
vector<int> v = {1, 2, 3};
v.insert(v.begin() + 1, 4); // 在第二个位置插入元素4
for (int i = 0; i < v.size(); i++) {
    cout << v[i] << " ";
}
cout << endl;

以上是vector容器的常用操作,vector还支持很多其他的操作,如排序、查找、删除等,具体可以参考C++的官方文档。需要注意的是,当vector的元素个数超过当前容量时,vector会重新分配一个更大的内存块,并将原有元素复制到新内存块中,这可能导致性能问题。因此,在使用vector时,可以通过调用reserve函数来预分配容量,避免频繁的内存分配复制。文章来源地址https://www.toymoban.com/news/detail-492108.html

到了这里,关于西安石油大学2023年第三届里奇杯编程大赛(初赛)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 西安石油大学 C++期末考试 重点知识点+题目复习(上)

    当使用 const 修饰变量、函数参数、成员函数以及指针时,以下是一些代码示例: 声明只读变量: 保护函数参数: 防止成员函数修改对象状态: 防止指针修改指向的值: 这些示例展示了如何使用 const 来声明常量、保护函数参数、防止成员函数修改对象状态以及防止指

    2024年02月11日
    浏览(25)
  • 西安石油大学数学建模校赛培训(2)matlab的使用

    MATLAB是MathWorks公司推出的一套高性能数值分析计算软件,其名字来源于\\\"Matrix Laboratory\\\"(矩阵实验室)的缩写。它将矩阵运算、数值分析、图形处理、编程技术等功能集成在一起,为科学计算、工程设计和数据分析提供了强大的平台。MATLAB的特点包括易于使用的高级编程语言、

    2024年03月28日
    浏览(31)
  • 上机实验二 设计单循环链表 西安石油大学数据结构

    (1)实验目的:掌握线性表的链式存储结构;掌握单循环链表及其基本操作的实现。 (2)主要内容:实现单循环链表的初始化、求数据元素个数、插入、删除、取数据元素等操作;用插入法建立带头结点的单循环链表;设计一个测试主函数验证所设计单循环链表的正确性。 掌握线性

    2024年02月07日
    浏览(32)
  • 西南石油大学PTA(期末)编程题题面

    本篇用于本人复习,部分代码参考相关博客(就是看头文件啦) 祝大家取得好成绩 定义一个有关人的 Person 类,内含属性: String name 、 int age 、 boolean gender 、 int id ,所有的变量必须为私有( private )。 注意: 属性顺序请严格按照上述顺序依次出现。 1.编写无参构造函数:

    2024年02月05日
    浏览(27)
  • 17届全国大学生智能汽车竞赛 中国石油大学(华东)智能视觉组 国特开源

    第一部分:art 矩阵库 透视变换 地图识别 卡尔曼滤波多目标追踪 第二部分:模型训练 环境配置 训练 量化 超模型 数据增强 目标检测 所有开源代码已上传到我的GitHub仓库。 因为寒假回家,大部分的代码都在实验室主机上。所以开源的代码大部分重新编写过,没有经过上车测

    2024年02月11日
    浏览(32)
  • 2023年第三届陕西省大学生网络安全技能大赛 web部分 wp

    总体来说还行,就是又感受到了py的成分,多的不说,星盟出的题,题目质量还是可以的,希望之后通过学习大佬的姿势来长长见识。 目录 EZPOP  RCE unserialize 首先来到页面   点击,就是空白页,查看源代码 F12都会进入空白页,猜测存在js在搞怪。 先打开一个空白页,再f12,

    2024年02月10日
    浏览(34)
  • 2023 年第十三届“MathorCup” C 题 包裹应急调运问题(解题思路)

    题目背景 电商物流网络由物流场地(接货仓、分拣中心、营业部等)和物流场地之间的运输线路组成。如果物流场地由于紧急情况而暂时或永久关闭,则由其处理的包裹将紧急转移至其他物流场地。这些因素将影响每条线路运输的包裹数量和每个物流场地处理的包裹数量。如

    2024年02月06日
    浏览(35)
  • 2023 年第三届长三角高校数学建模竞赛赛题浅析

    为了更好地让大家本次长三角比赛选题,我将对本次比赛的题目进行简要浅析。数模模型通常分为优化、预测、评价三类,而本次数学题目就正好对应着A、B、C分别为优化、预测、评价。整体难度不大,主要难点在于A题的优化以及B、C的数据收集。稍后,我将为大家收集一些

    2024年02月05日
    浏览(29)
  • 2023 年第三届长三角高校数学建模 C 题 考研难度知多少

    2023 年第三届长三角高校数学建模竞赛题目 (请先阅读 “ 长三角高校数学建模竞赛论文格式规范 ” ) C 题 考研难度知多少 据相关媒体报道, 2023 年考研可以称得上是 “ 最难 ” 的一年,全国研究生报 考人数突破新高达到 474 万人、部分考研学生感染新冠带病赴考、保研名

    2024年02月05日
    浏览(25)
  • IET独立出版 | EI检索 | 2023年第三届机械、航空航天与汽车工程国际会议

    会议简介 Brief Introduction 2023年第三届机械、航空航天与汽车工程国际会议(CMAAE 2023) 会议时间:2023年12月8 -10日 召开地点:中国·南京 大会官网:www.cmaae.org 航天是当今世界最具挑战性和广泛带动性的高技术领域之一,是推动国家科技进步的强大引擎,也是国家建设经济强国

    2024年02月11日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包