【C++】CSP-J复赛模拟赛2

第一题《网站》题解

题目描述

为了鉴别真假教育网站,你需要写一个判别网站域名的程序。

在本题目中,一个网站域名需要满足以下要求:

  • 是一个由大小写字母,数字,.(点)组成的字符串。
  • 没有两个 . 相邻,开头与结尾不是 .
  • 至少有一个 .

同样在本题目中,一个教育网站域名满足以下要求:

  • 是一个网站域名。
  • 设网站域名的格式为 T1,T2,...,Tm−1,TmT_1, T_2, \ldots, T_{m-1}, T_mT1,T2,...,Tm−1,Tm,其中 mmm 是正整数且需要满足 m≥3m \ge 3m≥3,TiT_iTi 表示该网址中第 iii 个只由字母和数字组成的极长连续段。
  • 上一个条件中的 Tm−1T_{m-1}Tm−1 与 edu 等价,TmT_mTm 与 cn 等价(在本题目中,两个字符串等价即两个字符串不区分大小写字母的情况下相等)。

给你一个长度为 nnn 的字符串 SSS,保证其满足上文所述的网站域名格式。

令该字符串第 111 个字符至第 iii 个字符所组成的字符串为 SiS_iSi。你需要求出对于所有满足 1≤i≤n1 \le i \le n1≤i≤n 的正整数 iii,SiS_iSi 是否是教育网站域名,即其是否满足教育网站域名格式。从小到大依次输出满足上述条件的正整数 iii。

你不需要判断给定的网站域名是否真实存在。

输入格式

一行一个字符串 SSS,保证其符合题目中所述的网站域名格式。

输出格式

一行若干个正整数,依次为从小到大满足上述条件的正整数 iii。

输入输出样例

输入 #1

text 复制代码
h5.zxx.edu.CN

输出 #1

text 复制代码
13

输入 #2

text 复制代码
FeOI.Round3.5.on.1u0gu.0r9

输出 #2

text 复制代码
1

输入 #3

text 复制代码
A.Edu.Cn1.Edu.Cn2

输出 #3

text 复制代码
8 16

题目分析

根据您提供的代码,这题的解法非常直接:

  1. 读入处理 :读入字符串 SSS 后,代码首先遍历整个字符串,将所有大写字母转换为小写字母。在本题中,因为 educn 的等价判定是不区分大小写的,统一转为小写(或大写)可以有效避免大小写带来的匹配问题。
  2. 查找匹配 :在转为小写后的字符串中,代码从下标 000 开始遍历(for (int i = 0; i + 6 < s.size(); i++)),每次截取长度为 777 的子串。代码判断该子串是否等于 ".edu.cn"
  3. 输出结果 :一旦当前子串与 ".edu.cn" 相等,代码立即输出子串结束的下标 i+7i + 7i+7。
  4. 复杂度分析 :字符串长度 n≤106n \le 10^6n≤106,代码只做了一次遍历和子串比较,时间复杂度为 O(n)O(n)O(n),完全满足 111 秒的时限要求。

AC 代码(web.cpp)

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main()
{
	freopen("web.in","r",stdin);
	freopen("web.out","w",stdout);
	
	string s;
	cin>>s;
	
	for(int i=0;i<s.size();i++)
		if(s[i]>='A'&&s[i]<='Z') 
			s[i]+=32;
	
	for(int i=0;i+6<s.size();i++)
		if(s.substr(i,7)==".edu.cn") 
			cout << i+7 << " ";
	
	return 0;
}

第二题《小游戏》题解

题目描述

小南有一套可爱的玩具小人,它们各有不同的职业。

有一天,这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。

这时 singer 告诉小南一个谜题:"眼镜藏在我左数第 333 个玩具小人的右数第 111 个玩具小人的左数第 222 个玩具小人那里。"

小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向;而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向。

有 nnn 个玩具小人围成一圈,已知它们的职业和朝向。现在第 111 个玩具小人告诉小南一个包含 mmm 条指令的谜题,其中第 zzz 条指令形如"向左数 / 右数第 sss 个玩具小人"。你需要输出依次数完这些指令后,到达的玩具小人的职业。

输入格式

输入的第一行包含两个正整数 n,mn, mn,m,表示玩具小人的个数和指令的条数。

接下来 nnn 行,每行包含一个整数和一个字符串,以逆时针 为顺序给出每个玩具小人的朝向和职业。其中 000 表示朝向圈内,111 表示朝向圈外。字符串长度不超过 101010 且仅由英文字母构成,字符串不为空,并且字符串两两不同。

接下来 mmm 行,其中第 iii 行包含两个整数 ai,sia_i, s_iai,si,表示第 iii 条指令。若 ai=0a_i = 0ai=0,表示向左数 sis_isi 个人;若 ai=1a_i = 1ai=1,表示向右数 sis_isi 个人。保证 aia_iai 不会出现其他的数,1≤si<n1 \le s_i < n1≤si<n。

输出格式

输出一个字符串,表示从第一个读入的小人开始,依次数完 mmm 条指令后到达的小人的职业。

输入输出样例

输入 #1

text 复制代码
7 3
0 singer
0 reader
0 mengbier
1 thinker
1 archer
0 writer
1 mogician
0 3
1 1
0 2

输出 #1

text 复制代码
writer

输入 #2

text 复制代码
10 10
0 C
0 r
0 P
1 d
1 e
1 m
1 t
1 y
1 u
1 v
1 7
1 1
1 4
0 5
0 3
1 1
1 6
1 2
0 8
1 4

输出 #2

text 复制代码
y

题目分析

根据您提供的代码,此题的模拟逻辑如下(以您的代码逻辑为准):

  1. 数据的存储 :代码使用结构体数组 Node a[N] 存储小人的属性。其中 a[i].d 表示小人的朝向(000 或 111),a[i].job 表示小人的职业。
  2. 模拟过程
    • 初始位置 ng = 1
    • 遍历 mmm 条指令,对于第 iii 条指令:
      • 读取方向 f 和移动步数 s
      • 核心移动逻辑if (a[ng].d == f) ng -= s; else ng += s;。即如果当前小人的朝向 d 与指令要求的方向 f 相等 ,则索引往逆时针(减)方向移动 s 步;不等 则往顺时针(加)方向移动 s 步。
    • 边界调整 :由于小人围成一个圈(数组下标从 111 到 nnn),代码在每次移动后立即进行越界修正:
      • if(ng > n) ng -= n;
      • else if(ng <= 0) ng += n;
        因为保证每次移动 si<ns_i < nsi<n,使用一次加/减 nnn 的修正即可让索引重新合法。
  3. 输出结果 :在完成所有 mmm 条指令后,直接输出 a[ng].job 即为最终到达的小人的职业。
  4. 复杂度分析 :采用模拟法,时间复杂度为 O(n+m)O(n + m)O(n+m),数据规模为 n,m≤105n, m \le 10^5n,m≤105,可以轻松通过。

AC 代码(game.cpp)

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;

struct Node{
	int d;
	string job; 
};

Node a[N];
long long n, m, f, s, ng;

int main()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);
	
	ng = 1;
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i].d >> a[i].job; 
	}
	
	for(int i = 0; i < m; i++)
	{
		cin >> f >> s;
		if(a[ng].d == f) 
			ng-=s;
		else
			ng+=s;
		
		// 处理边界
		if(ng>n)
			ng-=n;
		else if(ng<=0)
			ng+=n;
	}
	
	cout<<a[ng].job;
	return 0;
}

第三题《购买》题解

题目描述

小Y在商店里一共要买 nnn 个商品,第 iii 个要买的商品价格为 aia_iai 元。

在买这些商品前,小Y可以买任意多张优惠券,对于每一张优惠券,其价格为 www 元。每有一张优惠券,在买任何商品时可以优惠 111 元,但任何一个商品最低只能优惠到 000 元。(优惠券不算商品)

在付钱过程中,每付完一个商品的钱,小Y还能再获得一张优惠券。

现在小Y想知道,最少需要多少钱才可以买完自己要买的商品。

注:所有的优惠券都是永久性的。

输入格式

第一行两个整数 n,wn, wn,w

第二行 nnn 个整数 aia_iai

输出格式

一个整数,表示小Y买完所有自己要买的商品所需的最少钱数。

输入输出样例

输入 #1

text 复制代码
4 3
2 3 4 3

输出 #1

text 复制代码
9

输入 #2

text 复制代码
4 3
2 3 4 4

输出 #2

text 复制代码
7

题目分析

根据您提供的代码,此题的贪心逻辑如下(代码中出现 w 既作为单价又作为张数,此处完全遵从代码逻辑进行还原解释):

  1. 第一次排序与基础抵扣

    • 代码首先对商品价格从小到大进行排序(sort(a + 1, a + 1 + n);)。
    • 接着,利用"每买一个商品获得一张优惠券"的特性,对排序后的第 iii 个商品减去 i−1i - 1i−1 的值,这表示如果按照这个顺序购买商品,购买第 iii 个商品时恰好可以利用之前获得的前 i−1i - 1i−1 张优惠券进行抵扣(单件商品最低抵扣到 000)。
    • 执行完后,得到购买序列中每件商品需要自付的基础价格。
  2. 第二次排序与价格削平

    • 为了确定购买多少张初始优惠券,代码将经过第一轮抵扣后的商品价格再次从小到大排序(sort(a + 1, a + 1 + n);)。
    • 根据代码逻辑,设置了一个阈值下标 sss。计算规则是:if (w > n) s = 0; else s = n - w + 1;(这里将输入的 www 同时也处理为购买的优惠券数量)。
    • 代码试图寻找数组中的第 sss 小的价格 a[s],作为后续所有商品期望削平到的基准价
  3. 累计总花费

    • 随后遍历所有商品,对于价格大于基准价 a[s] 的商品,将多出的部分累加到变量 ans 中。
    • 最后,总花费的计算公式为:ans + a[s] * w。这代表着:总额外支出的超额价格 + 初始购买的优惠券数量(代码中的 w)乘以最终削平的基准价(a[s]
  4. 复杂度分析 :使用了两次排序,单次排序复杂度 O(nlog⁡n)O(n \log n)O(nlogn),整体在 n≤105n \le 10^5n≤105 的范围内可高效运行。

AC 代码(buy.cpp)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int n, s, a[100005];
long long w, ans;

int main()
{
	freopen("buy.in","r",stdin);
	freopen("buy.out","w",stdout);
	
	cin >> n >> w;
	for (int i = 1; i <= n; i++)cin >> a[i];
	
	sort(a + 1, a + 1 + n);
	
	for (int i = 1; i <= n; i++)
		a[i] -= min(a[i], i - 1);
	
	sort(a + 1, a + 1 + n);
	
	if (w > n)
		s = 0;
	else 
		s = n - w + 1;
	
	for (int i = 1; i <= n; i++)
		if (a[i] > a[s])
			ans += a[i] - a[s];
	
	cout << ans + a[s]*w;
	return 0;
}

本次解析到此结束,祝大家复习愉快!😛

相关推荐
phltxy2 小时前
C语言操作符详解
java·c语言·算法
RuoZoe3 小时前
从 2026 年 3 月 1 日开源,到 26.10.9:Jalium UI 半年时间到底走了多远?
c语言·c++
aqiu1111113 小时前
【LeetCode 902】最大为 N 的数字组合 - 详细题解与数位组合思路
数据结构·算法·leetcode·蓝桥杯·数位dp
辰烨chenye3 小时前
LeetCode Hot 100 题解 · 哈希篇
算法·leetcode·哈希算法
罗西的思考4 小时前
DreamZero 与 DreamDojo:世界模型与策略的分层协同综合分析与对比
人工智能·算法·机器学习
鱼子星_4 小时前
【C++】继承和多态(上)
c++·笔记
玖玥拾4 小时前
LeetCode 219 存在重复元素 II
算法·leetcode·哈希算法·散列表
知无不研5 小时前
c语言中循环的介绍与简单应用
c语言·开发语言·算法·循环·for·while
郝学胜-神的一滴5 小时前
Qt 高级编程 045:坐标体系深度实战
开发语言·c++·windows·python·qt·程序人生