Contest3383 - 2024寒假集训 进阶训练赛 (七)(部分题解)

目录

A.分离出整数n从右边数第k个数字,递归实现

B.Xu Xiake in Henan Province

C.Fibonacci Sequence

D.一只小蜜蜂

E.Team Shirts/Jerseys

F.查找与给定值最接近的元素

G.【蓝桥杯2022初赛】扫雷

H.【蓝桥杯2022初赛】刷题统计

I.Another country

K.三只熊猫蛋

L.Bob和Alice(2)


A.分离出整数n从右边数第k个数字,递归实现

题目描述

在程序中定义一函数digit(n,k),它能分离出整数n从右边数第k个数字。

输入

正整数n和k。

输出

第k个数字(若不存在则输出0)

AC代码
#include 
using namespace std;

signed main()
{
	string s;//用字符串储存数字 
	int k;
	cin>>s>>k;
	if(s.size()

B.Xu Xiake in Henan Province

题目描述

少林寺是中国佛教禅宗祖庭,坐落于河南省登封市。少林寺始建于公元5世纪,至今仍是少林佛教的主要寺庙。
龙门石窟是中国佛教艺术最好的代表之一。这些佛像位于今天的河南省洛阳市以南12km 处,里面有数以万计的佛陀和其弟子的雕像。
根据历史记载,白马寺是中国第一座佛教寺庙,由汉朝皇帝发起建于公元68年,坐落于东汉首都洛阳。
云台山位于河南省焦作市修武县。云台地质公园景区被国家旅游局列为AAAAA 级风景区。云台瀑布位于云台地质公园内,瀑布高 314m,号称是中国最高的瀑布。
它们是河南省最著名的地方景点。
现在是时候判断一下旅行者的水平了。所有旅行者都可以根据他们所到过的景点的数量来分类。
一个旅行者游览了上述提到的0个景点,那么他就是“Typically Otaku”。
一个旅行者游览了上述提到的1个景点,那么他就是“Eye-opener”。
一个旅行者游览了上述提到的2个景点,那么他就是“Young Traveller”。
一个旅行者游览了上述提到的3个景点,那么他就是“Excellent Traveller”。
一个旅行者游览了上述提到的4个景点,那么他就是“Contemporary Xu Xiake”。
请确认旅行者的水平。

输入

输入包含多组测试样例,第一行包含一个正整数T,表示最多10^4个测试样例的数量。
对于每个测试案例,唯一的一行包含4个整数A1、A2、A3和A4,其中Ai是旅行者游览第i个景点的次数,0≤A1、A2、A3、A4≤100。
如果Ai是0,那就意味着旅行者从来没有去过第i个景点。

输出

对于每个测试样例,输出一行,其中包含一个字符串,表示旅行者的分类,该字符串应该是

"Typically Otaku","Eye-opener","Young Traveller","Excellent Traveller","Contemporary Xu Xiake" 其中之一。

AC代码
#include 
using namespace std;

signed main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int a,flag=0;
		for(int i=0;i<4;i++)
		{
			cin>>a;
			if(a!=0)flag++;
		}
		if(flag==0)
		cout<<"Typically Otaku"<

C.Fibonacci Sequence

题目描述

斐波那契数列,又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。
在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用。 
斐波那契数列定义如下:F1=1,F2=1,F3=2,F4=3,…………,Fn=Fn-1+Fn-2(n>2)
编写程序,输出斐波那契数列第n个数字
 

输入

一个正整数n(1≤n≤90 )

输出

一个正整数 输出斐波那契数列第n个数字

AC代码
#include 
using namespace std;
#define int long long//数据会超出int范围 
int a[100];
void fibo()
{
	a[0]=1,a[1]=1;
	for(int i=2;i<90;i++)
	a[i]=a[i-1]+a[i-2];
}
signed main()
{
	int n;
	cin>>n;
	fibo();
	cout<

D.一只小蜜蜂

题目描述

有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
其中,蜂房的结构如下所示
 

输入

输入数据的第一行是一个整数N,表示测试实例的个数。
然后是N 行数据,每行包含两个整数a和b (0

输出

对于每个测试实例,请输出蜜蜂从蜂房a爬到蜂房b的可能路线数,每个实例的输出占一行。

AC代码
#include 
using namespace std;
#define int long long//数据会超出int范围 
/*思路:每次都只能从i,走到i+1或i+2,所以走到i的方法就是走到i-1和i-2
的方法数之和,本题实质就是斐波那契数列的应用*/
int a[100];
void fibo()
{
	a[0]=1,a[1]=1;
	for(int i=2;i<90;i++)
	a[i]=a[i-1]+a[i-2];
}
signed main()
{
	int b,e,n;
	fibo();
	cin>>n;
	while(n--)
	{
		cin>>b>>e;
		if(e-b>0)
		cout<

E.Team Shirts/Jerseys

题目描述
传奇数学家特拉维斯和他的朋友们正在一个娱乐(rec)联盟中进行竞争性编程。特拉维斯有n个朋友,他的朋友希望为这个竞争激烈的编程联盟表现出团结感,所以他们挥霍了球队的衬衫/球衣,每个球衣的背面都有一个介于1到99(含)之间的整数。Travis的每个朋友都已经选择了自己的(不一定是不同的)球衣号码,所以我们有一个n个整数列表。Travis 现在需要选择他的球衣号码来完成 n+1 整数列表。Travis 还将选择 1 到 99(含)之间的整数,并且他不必选择与朋友选择的数字不同的数字(即,他可以选择复制球衣号码)。
尽管特拉维斯可以选择任何球衣号码,但他想说明为什么他被认为是一个传奇的数学家。Travis 有一个最喜欢的正整数,他想选择他的球衣号码,这样他就能够从 n+1 整数列表中选择一组数字,将这组数字连接在一起,并在没有额外前导或尾随数字的情况下达到他最喜欢的整数(因为 Travis 想要他最喜欢的整数,而不是其他整数, 他试图在没有任何额外的尾随或前导数字的情况下这样做)。
特拉维斯很幸运地选择他的球衣号码。现在他只需要确定他是否可以选择一些数字来保证他可以形成他最喜欢的整数。例如,假设 Travis 的朋友选择了球衣号码 3、10、9 和 86。然后,通过选择数字75,Travis可以形成他最喜欢的正整数8,675,310。请注意,特拉维斯不需要使用9号球衣。
Contest3383 - 2024寒假集训 进阶训练赛 (七)(部分题解)_第1张图片
请注意,如果特拉维斯选择使用球衣号码,他必须完全使用号码,即他不能只使用号码中的一些数字。例如,如果他决定在上面的示例中使用75,则必须使用“75”;他不能只使用“7”或只使用“5”。还要注意的是,如果他想多次使用特定的球衣号码,他必须有多个朋友拥有该球衣号码。例如,如果他想多次使用75,他必须有多个数字75的朋友(当然,他也可以为自己选择75,以增加n + 1数字列表中75的出现次数)。我们现在必须打破特拉维斯非常气质的秘密!他往往很容易获得和失去朋友(对于整个团结的事情来说,这太多了);他也比繁忙的十字路口的灯光变化更频繁地改变他最喜欢的整数。出于这些原因,Travis需要你的帮助来编写一个程序来解决这个问题,以便为一般的朋友和最喜欢的号码。
问题:
给定一组表示朋友球衣号码的正整数和一个最喜欢的整数,确定Travis是否可以选择一个球衣号码(为自己),该号码可以通过连接零个或多个朋友的数字来创建他最喜欢的整数,并且可能是他的号码。此外,由于这是一个rec联赛,朋友列表可能包含重复的球衣号码,特拉维斯可以为他的球衣选择一个已经选择的号码。
输入

输入的第一行正好包含一个正整数 t(t < 1,000,000,000),表示 Travis 最喜欢的整数。
第二行输入正好包含一个正整数 n(n ≤ 25),表示 Travis 今天有多少朋友。
下一行包含n个空格分隔的整数,表示Travis的每个朋友选择的球衣号码。
球衣号码将介于 1 和 99(含)之间,并且没有前导零,例如,输入的球衣号码为 7,但不是 07。

输出

如果特拉维斯能够与(或不与)他的一组朋友一起达到他最喜欢的整数,请打印1 ;否则输出 0。

输出时每行末尾的多余空格,不影响答案正确性

AC代码 
#include 

using namespace std;
vector seq; // 用于存储输入数字的每一位数字
int n, num; // 存储输入值的变量
int st[100]; // 存储1到99每个数字的出现次数

// 深度优先搜索函数
int dfs(int u, bool used) {
    if (u == seq.size()) return 1; // 基本情况:如果 u 达到序列的末尾,返回 1
    if (seq[u] == 0) return 0; // 如果当前数字为0,返回 0
    if (st[seq[u]]) { // 如果当前数字的出现次数不为0
        st[seq[u]]--; // 减少当前数字的出现次数
        if (dfs(u + 1, used)) return 1; // 递归调用dfs处理下一个数字
        st[seq[u]]++; // 恢复当前数字的出现次数
    } else if (!used && dfs(u + 1, true)) return 1; // 如果当前数字不可用且未被使用过,递归调用dfs处理下一个数字
    if (u < seq.size() - 1) { // 如果序列中还有更多数字
        if (st[seq[u] * 10 + seq[u + 1]]) { // 如果由当前数字和下一个数字组成的两位数的出现次数不为0
            st[seq[u] * 10 + seq[u + 1]]--; // 减少两位数的出现次数
            if (dfs(u + 2, used)) return 1; // 递归调用dfs处理下两个数字
            st[seq[u] * 10 + seq[u + 1]]++; // 恢复两位数的出现次数
        } else if (!used && dfs(u + 2, true)) return 1; // 如果两位数不可用且未被使用过,递归调用dfs处理下两个数字
    }
    return 0; // 如果没有找到有效的排列,返回 0
}

int main() {
    cin >> num; // 输入数字
    while (num) seq.push_back(num % 10), num /= 10; // 提取数字的每一位并存储在序列seq中
    reverse(seq.begin(), seq.end()); // 反转seq中数字的顺序
    cin >> n; // 输入数字的个数
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        st[x]++; // 输入数字并增加其出现次数
    }
    cout << dfs(0, false) << endl; // 调用dfs函数并输出结果
    return 0;
}

F.查找与给定值最接近的元素

题目描述

在一个非降序列中,查找与给定值最接近的元素

输入

第一行包含一个整数n,为非降序列长度。(1<=n<=100000)
第二行包含n个整数,为非降序列个元素有。所有元素的大小均再0-100000000.
第三行包含一个整数m,为要询问的给定值的个数 1<=m<=10000
接下来的m行,每行一个整数,为要询问最接近的元素的给定值。所有给定值的大小均在0-1000000000.

输出

m行,每行一个整数,为要询问最接近元素的给定值,保持输入顺序。若有多个值满足条件,则输入最小的一个。

AC代码 
#include 
using namespace std;
#define int long long
int a[100005];
signed main()
{
	int n,m;
	cin>>n;
	for(int i=0;i>a[i];
	cin>>m;
	while(m--)
	{
		int x;
		cin>>x;
		if(x<=a[0])
		cout<=a[n-1])
		cout<=a[i]&&x<=a[i+1])
				{
					if((x-a[i])<=(a[i+1]-x))
					cout<

G.【蓝桥杯2022初赛】扫雷

题目描述

小明最近迷上了一款名为《扫雷》的游戏。
其中有一个关卡的任务如下,在一个二维平面上放置着 n 个炸雷
第 i 个炸雷(xi, yi, ri) 表示在坐标(xi, yi) 处存在一个炸雷,它的爆炸范围是以半径为 ri 的一个圆。
为了顺利通过这片土地,需要玩家进行排雷。
玩家可以发射 m 个排雷火箭,小明已经规划好了每个排雷火箭的发射方向。
第 j 个排雷火箭(xj, yj, rj) 表示这个排雷火箭将会在(xj, yj) 处爆炸,它的爆炸范围是以半径为 rj 的一个圆,
在其爆炸范围内的炸雷会被引爆。同时,当炸雷被引爆时,在其爆炸范围内的炸雷也会被引爆。
现在小明想知道他这次共引爆了几颗炸雷?
你可以把炸雷和排雷火箭都视为平面上的一个点。
一个点处可以存在多个炸雷和排雷火箭。当炸雷位于爆炸范围的边界上时也会被引爆。

输入

输入的第一行包含两个整数n、m.
接下来的 n 行,每行三个整数xi, yi, ri,表示一个炸雷的信息。
再接下来的 m 行,每行三个整数xj, yj, rj,表示一个排雷火箭的信息。
40% 的评测用例:0 ≤ x, y ≤ 10^9; 0 ≤ n,m ≤ 10^3; 1 ≤ r ≤ 10:
100% 的评测用例:0 ≤ x, y ≤ 10^9; 0 ≤ n,m ≤ 5 × 10^4; 1 ≤ r ≤ 10:

输出

输出一个整数表示答案。

AC代码 

具体思路见下(本人较菜) 

https://blog.csdn.net/w20221013/article/details/130043459?ops_request_misc=&request_id=&biz_id=102&utm_term=%E3%80%90%E8%93%9D%E6%A1%A5%E6%9D%AF2022%E5%88%9D%E8%B5%9B%E3%80%91%E6%89%AB%E9%9B%B7&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-130043459.nonecase&spm=1018.2226.3001.4187

#include 
using namespace std;
typedef long long LL;
const int M = 999997;
const int Base = 1e9 + 1;
int res;
LL hash1[M]; //hash1用于维护find函数
int hash2[M],hash3[M],book[M]; //hash2:地雷在某点的出现次数 hash3:某点的地雷半径 book:标记该点是否被搜索
//Base进制编码降维
LL get_key(int x,int y)
{
    return (LL)x * Base + y;
}
//手写哈希函数
int find(LL x)
{
    int t = (x % M + M) % M;
    while(hash1[t]!=-1&&hash1[t]!=x)
    {
        t++;
        if(t==M) t=0;
    }
    return t;
}
//判断(x2,y2)是否位于(x1,y1,r1)的范围内
bool judge(int x1,int y1,int x2,int y2,int r)
{
    int d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
    return d <= r*r;
}
//dfs
void dfs(int x,int y,int r)
{
    for(int i=-r;i<=r;i++)
        for(int j=-r;j<=r;j++)
        {
            int dx = x + i;
            int dy = y + j;
            LL t = get_key(dx,dy);
            if(hash2[find(t)]&&judge(x,y,dx,dy,r)&&!book[find(t)])
            {
                res += hash2[find(t)]; //答案加上该点地雷个数
                book[find(t)] = 1; //标记为已搜索
                dfs(dx,dy,hash3[find(t)]); //搜索下一个点
            }
        }
    return;
}
int main()
{
    int n,m;
    cin>>n>>m;
    memset(hash1,-1,sizeof hash1); //hash1初始化为空
    for(int i=0;i>x>>y>>r;
        LL t = get_key(x,y);
        hash1[find(t)] = t; //维护哈希函数
        hash2[find(t)]++; //统计该点地雷数量
        hash3[find(t)] = max(r,hash3[find(t)]); //记录该点地雷半径的最大值
    }
    for(int i=0;i>x>>y>>r;
        dfs(x,y,r); //从每一个排雷火箭引爆点开始dfs
    }
    cout<

H.【蓝桥杯2022初赛】刷题统计

题目描述

小明决定从下周一开始努力刷题准备蓝桥杯竞赛。
他计划周一至周五每天做 a 道题目,周六和周日每天做 b 道题目。
请你帮小明计算,按照计划他将在第几天实现做题数大于等于 n 题?

输入 

输入一行包含三个整数a, b 和n.
对50% 的评测用例:1 ≤ a, b, n ≤ 10^6;
对100% 的评测用例:1 ≤ a, b, n ≤ 10^18

输出 

输出一个整数代表天数。

AC代码 
#include 
using namespace std;
#define int long long

signed main()
{
	int a,b,n;
	cin>>a>>b>>n;
	int p=5*a+2*b;//一周可以完成p道题 
	int n1=n/p,n2;
	int res=n-n1*p;
	if(res<=5*a)
	n2=res/a+1;
	else 
	n2=(res-5*a)/b+1+5;
	cout<

I.Another country

题目描述

卢卡为了救他身边病危的精灵,只好去远在第二大陆的精灵之国采取

宝贵的药物。他来到这个国家时被这个新国家的日期表示方式搞晕了,

他不知道月份和年份哪个在前哪个在后,但他得赶快拿到药物

着急的他求助于你,请你告诉他叭

给定一个长度为4的字符串

如果是YYMM形式 就输出YYMM

如果是MMYY形式 就输出MMYY

如果两者都可以 就输出AMBIGUOUS

如果两者都不行 就输出NA

输入
一个长度为4的字符串S
输出
YYMM,MMYY,AMBIGUOUS 或 NA.
AC代码 
#include 
using namespace std;
#define int long long

signed main()
{
	string s;
	cin>>s;
	int n1,n2;
	n1=(s[0]-'0')*10+(s[1]-'0');
	n2=(s[2]-'0')*10+(s[3]-'0');
	//月份必须不大于12且不等于0,年份无限制 
	if(n1>12||n1==0)
	{
		if(n2>12||n2==0)cout<<"NA";
		else cout<<"YYMM";
	}
	else
	{
		if(n2>12||n2==0)cout<<"MMYY";
		else cout<<"AMBIGUOUS";
	}
}

K.三只熊猫蛋

题目描述

Zheng被T暴打了很伤心,T为了安慰Zheng,给了他一坨熊猫蛋。但是Zheng很生气的对T说,熊猫明明是没有蛋的啊!但这跟T安慰Zheng又有什么关系呢?

回归正题,每个蛋上有一个字符串,但是熊猫蛋有一个神奇的功能,可以随意打乱字符串的顺序。那么问题来了,T想让Zheng算算有多少对蛋,符合一个蛋上的字符串按照任意顺序排列后可以得到另外一个蛋上的字符串,请聪明善良又可爱的你告诉ta吧

输入

2<=N<=1e5(N为熊猫蛋个数)
每个蛋上的字符串长度都为10,并且都是小写字母
每个字符串都是不相同的,因为每个熊猫蛋都是不同厂家生产的

输出

对数

AC代码 
#include 
using namespace std;
#define int long long

signed main()
{
	int n,ans=0;
	cin>>n;
	string s[100005];
	for(int i=0;i>temp;
		sort(temp.begin(),temp.end());//对输入的字符串内部按字母顺序排序 
		s[i]=temp;
	}
	map mp;//定义map容器,关键字为字符串,键值表示相同字符串的数目 
	map::iterator it;
	for(int i=0;isecond;
		ans+=n*(n-1)/2;//有n个相同字符串,则有n*(n-1)/2对相同的串 
	}
	cout<

L.Bob和Alice(2)

题目描述

Bob为了给Alice过生日
做了n顿丰富的大餐
他提前制定好了n顿大餐的计划
从1到n编号
由于Bob有每种癖好
在上餐的时候会按照编号为A1 A2 .......An的顺序上餐
Aince对每顿餐的满意度也不一样
对于编号为i的大餐,她会获得b[i]的满意度
特别的
她从吃第二顿大餐开始 如果当前大餐编号i是上一个吃的大餐的编号j + 1的话
她会额外获得c[j]的满意度
现在Bob想知道Alice按照上餐顺序吃完所有的大餐可以获得的满意度
你可以告诉他吗

输入

n
A1 A2 .......An
B1 B2 .......Bn
C1 C2 .......Cn−1
2 <= n <= 20
1 <= Ai <= n
1 <= Bi, Ci <= 50

输出

Alice按照上餐顺序吃完所有的大餐可以获得的满意度

AC代码 
#include 
using namespace std;
#define int long long

signed main()
{
	int n;
	cin>>n;
	int a[25],b[25],c[25];
	for(int i=1;i<=n;i++)
	cin>>a[i];
	for(int i=1;i<=n;i++)
	cin>>b[i];
	for(int i=1;i<=n-1;i++)
	cin>>c[i];
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans+=b[a[i]];
		if(i!=n&&a[i+1]==a[i]+1)
		ans+=c[a[i]];
	}
	cout<

你可能感兴趣的:(算法)