2021 第三届浙江省高职院校新生联赛

关于本场比赛的感受:只要服务器正常不卡亿点点,我也能多开几道题。看到题卡个七八分钟,判题判了帮个小时也没出来表示做的很难受,就不太想做的样子。不过毕竟排行榜有真实姓名,还是煎熬的打了下来。

目录

  1. 曹子孝八门金锁

  2. 邓士载偷渡阴平

  3. 张文远威震逍遥

  4. 吕子明白衣渡江

  5. 赵子龙单骑救主

  6. 刘玄德三顾茅庐

  7. 诸葛亮草船借箭

  8. 吕奉先辕门射戟

  9. 姜伯约北伐中原

  10. 曹孟德青梅煮酒

  11. 陆伯言火烧连营

  12. 关云长千里单骑

  13. 黄月英奇门遁甲

1.曹子孝八门金锁

题目链接:

题目描述:

现在曹仁改良了他的八门金锁阵,这是一个n*m的阵法,阵法中的每一个方格都存在着一个数字。这个改良后的八门金锁阵非常奇怪,最外圈为正能量,向内一圈为负能量,再向内一圈又为正能量,如此交替循环。现在徐庶想知道,这个阵法的正负能量相抵后,最终的阵法能量总和值为多少。你可以帮徐庶计算一下嘛?

注意:如果阵法出现了1*M,N*1,2*2的局面,则整体为一圈

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入两个正整数 n 和 m (1 <= n,m <= 1000),分别代表阵法的行数和列数。接下来n行,每行输入m个非负整数zi(0 <= zi <= 100)。

输出描述:

对于每组测试样例,输出正负相抵之后的阵法能量总和。

样例输入

3 3

1 2 3

4 5 6

7 8 9

样例输出

35

解题心得:

看到这道题直接类似蛇形矩阵来一发即可!

给个变量k来记录是正能量还是负能量,循环的方向为东南西北。由图可知,改变k的正负值的临界点只可能发生在变量d为3时(即方向为北时)。

易知临界点为(i,j)【当且仅当i == j时】

代码如下:

#include<iostream>
#include<cstring>

using namespace std;

const int N = 1e3 + 5;

int n, m;
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};    //循环方向
int f[N][N];
bool st[N][N];

int main()
{
 	while(cin>>n>>m){
 		int val = 0;
 		memset(st, false, sizeof st);
	 	for(int i = 1; i <= n; i ++ )
	 		for(int j = 1; j <= m; j ++ )
	 			cin>>f[i][j];
		int k = 1, d = 0, x = 1, y = 1;
		st[x][y] = true;
		val += f[x][y];
		for(int i = 2; i <= n * m; i ++ ){
			int a = dx[d] + x, b = dy[d] + y; 
			if(a >= 1 && b >= 1 && a <= n && b <= m && !st[a][b]){
				st[a][b] = true;
				val += k * f[a][b];	
			}
			else{
				if(d == 3)	k *= -1;
				d = (d + 1) % 4;
				a = dx[d] + x, b = dy[d] + y;
				val += k * f[a][b];
				st[a][b] = true;
			}
			x = a, y = b;
		}
		cout<<val<<'\n';	
	}
	return 0;
}


2.邓士载偷渡阴平

题目描述:

现在已知邓艾的小部队经过了蜀国屯粮之地,屯粮之地有N个粮仓,每一个粮仓的粮食储量全部已经被邓艾的侦查小队侦查清楚。但是每攻占一个粮仓需要消耗1000粮草,邓艾对于每一个粮仓可以自由选择是否进攻。现在请你帮邓艾计算一下,通过合理的选择,邓艾最多可以获得多少净收入的粮草?laingcha

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入一个整数 N (1 <= N <= 20000)代表粮仓的总数,第二行输入N个整数Ni(0 <= Ni <= 200000),代表第 i 个粮仓所含的粮草总量。

输出描述:

对于每组测试样例,输出最多可以获得的净收入粮草数量。

样例输入

5

999 1000 1201 500 1003

样例输出

204

解题心得:

如果该粮仓超过1000的粮草,那么加上差值即可!

代码如下:

#include<iostream>

using namespace std;

typedef long long ll;

int main(){
	int t;
	while(cin>>t){
		ll val = 0;
		for(int i = 1; i <= t; i ++ ){
			int x;
			cin>>x;
			int u = max(0, x - 1000);
			val += u;
		}
		cout<<val<<'\n';
	}
	return 0;
}

3.张文远威震逍遥 

题目链接:https://nwanna.cn/problems/ZJYYC1313

题目描述:


张辽击败孙权后,发现了孙权的一个宝藏库。这个宝藏库由N个地洞组成,这N个地洞排列在一条直线上。每个地洞上有一块木板,每个地洞里都有孙权藏匿的宝藏。但是每块木板上压着一块石头,马上要过年了,张辽准备把所有的宝藏都取出来犒赏三军,现在张辽站在其中一块木板上,他能做以下三种操作:
1.往左或者向右走一步
2.把当前木板上的一块石头扔到任意一块木板上
3.当木板上没有石头了就取出宝藏
张辽想以最快的速度拿出所有的宝藏,你能告诉他最少需要多少次操作吗?

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入两个正整数 n 和 m (2 <= n <= 5000)(1 <= m <= n),分别代表张辽一共有多少个地洞和当前站在第几块木板上。

输出描述:

对于每组测试样例,输出最少需要多少次操作。

样例输入

2 2

样例输出

6

解题心得:

如果第m块木板左边的木板数量<右边的木板数量,那么先左走到底在向右到底,反之易得。

其中过程模拟一下即可。

代码如下:

#include<iostream>

using namespace std;

int main()
{
 	int n, m;	//地洞,位置 
 	while(cin>>n>>m){
 		int val = 6;
 		int mid = n / 2;
 		if(m <= mid)	m = n - m + 1;
 		int cou = max(0, n - m - 1);
 		val += cou * 3 + (n - m + 3) + (m - 2) * 3;
		cout<<val<<'\n';	
	}
	return 0;
}

4.吕子明白衣渡江 

题目链接:https://nwanna.cn/problems/ZJYYC1316

题目描述:


现在吕蒙需要在部下的士兵中挑选一部分士兵来作为夺取荆州的先头突击队,他指定了一个规则,他随意选取了两个数字N和M,然后让部下从1开始报数。如果部下士兵的报出的数字恰好能被吕蒙选取的两个数字中任意一个整除,那么该士兵就会被编入突击队。现在吕蒙想知道,第K个被编入突击队的士兵的编号是多少?由于吕蒙幼年书读的少,被称之为吴下阿蒙,所以他现在特地来求助你帮帮他。

输入描述:

测试样例由多组测试数据组成。每组测试数据第一行输入三个正整数K(1 <= K <= 1e9)N,M(2 <= N,M <= 40000)分别代表吕蒙想知道第K个被编入突击队的士兵编号以及吕蒙选取的两个整数。

输出描述:

对于每组测试样例,输出第K个被编入突击队的士兵编号。由于答案可能很大,所以你需要将答案对998244353取模。

测试样例:

样例输入

5 1 3

样例输出

5

解题心得:

二分即可

代码如下:

#include<iostream>
 
using namespace std;

typedef long long ll;
const int mod = 998244353;

ll gcd(ll a,ll b){
    return b ? gcd(b, a % b) : a;
}

int main(){
	ll k, n, m;
	while(cin>>k>>n>>m){
		ll min1 = n, max1 = m;
		if(n > m) min1 = m, max1 = n;
		if(max1 % min1 == 0)	cout<<min1 * k % mod<<'\n';
		else{
			ll lcm = n * m / gcd(n, m);
			ll l = 1, r = k;
			while(l <= r){
				ll mid = (l + r) / 2;
				ll u = mid * min1 / max1, val = mid + u;
				val -= mid * min1 / lcm;
				if(val < k)	l = mid + 1;
				else if(val > k)	r = mid;
				else{
					cout<<mid * min1 % mod<<'\n'; 
					break;
				}
				ll center = mid * min1, q = (mid - 1) * min1, h = (mid + 1) * min1;
				if(mid * min1 != u * max1){
					if(k == val + 1){
						ll sum = (u + 1) * max1;
						if(sum >= center && sum <= h){
							cout<<(u + 1) * max1 % mod<<'\n';
							break;
						}
					}
					else if(k == val - 1){
						ll sum1 = u * max1;
						if(sum1 >= q && sum1 <= center){
							cout<<u * max1 % mod<<'\n';
							break;
						}
					}	
				}else{
					if(k == val + 1){
						cout<<h % mod<<'\n';
						break;
					}
					else if(k == val - 1){
						cout<<q % mod<<'\n';
						break;
					}
				}
				
			}	
		}
	}
	return 0;
}

5.赵子龙单骑救主 

题目链接:https://nwanna.cn/problems/ZJYYC1315

题目描述:


现在赵云不慎中了曹操的诡计,被曹操困在了一个n*m的八门金锁阵中。现在赵云必须想办法打败位于阵法出口处的曹操大将典韦才能护送阿斗回到蜀汉阵营。已知阵法中散落着数值为1~9之间的武器,赵云如果捡到了武器,则会提升相应数值的攻击力,只有赵云的攻击力不低于典韦的攻击力,才能打败典韦突围出阵法。阵法中赵云所有走过的路都不能再次行走,否则容易遭到曹操的埋伏。赵云可以在阵法中往上下左右四个方向移动,现在赵云将阵法的地图交给了你,请你帮他计算一下,他到底有没有机会突破出阵法?

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入两个正整数n,m(2 <= n,m <= 7)代表阵法的大小。接下来输入一个n*m的矩阵,矩阵由以下几种字符组成:

字符 . 代表这是可以走的道路
字符 X 代表这是一堵墙,赵云不可以走到墙上
数字 1~9, 代表这是一把武器,赵云如果捡到,则可以提升对应数值的攻击力
字符 S,赵云的起始位置
字符 B,典韦的位置(阵法的出口)


最后一行输入两个整数 a,b (0 <= a,b <= 100),分别代表赵云的初始攻击力和典韦的攻击力。

输出描述:

对于每组测试样例,如果赵云最后能够成功逃出阵法,则输出YES。否则请输出NO。

样例输入

3 3

S.3

...

..B

5 8

样例输出 

YES

解题心得:

简单的dfs即可。但是由于本题数据出错了,出现了数字0,而非1-9,导致wa了。所以各位注意。

代码如下:

#include<iostream>
#include<cstring>

using namespace std;

const int N = 10;

int n, m;
int z1, z2, dw1, dw2;
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
char g[N][N];
bool st[N][N];

bool dfs(int zy1, int zy2, int pow1, int pow2){
	if(zy1 == dw1 && zy2 == dw2 && pow1 >= pow2)	return true;
	else if(zy1 == dw1 && zy2 == dw2 && pow1 < pow2)	return false;
	for(int i = 0; i < 4; i ++ ){
		int a = dx[i] + zy1, b = dy[i] + zy2;
		if(a >= 1 && b >= 1 && a <= n && b <= m && !st[a][b] && g[a][b] != 'X'){
			st[a][b] = true;
			int val = pow1; 
			if(g[a][b] >= '1' && g[a][b] <= '9')	val += g[a][b] - '0';
			if(dfs(a, b, val, pow2))	return true;
			st[a][b] = false;
		}
	}
	return false;
}

int main(){
 	while(cin>>n>>m){
 		int res = 0;
 		memset(st, false, sizeof st);
 		for(int i = 1; i <= n; i ++ )
			for(int j = 1; j <= m; j ++ ){
				cin>>g[i][j];
				if(g[i][j] >= '1' && g[i][j] <= '9')	res += g[i][j] - '0';
				if(g[i][j] == 'S')	z1 = i, z2 = j, st[i][j] = true;
				if(g[i][j] == 'B')	dw1 = i, dw2 = j;
			}
		int p1, p2;
		cin>>p1>>p2;
		if(p1 + res < p2)	cout<<"NO\n";
		else{
			bool val = dfs(z1, z2, p1, p2);	
			if(val)	cout<<"YES\n";
			else	cout<<"NO\n";	
		}
	}
	return 0;
}


6. 刘玄德三顾茅庐

题目描述:


今天是2021年第三届浙江省高职院校新生联赛,希望同学们都能取得理想的成绩,祝愿人人都能AK。为了给自己加个油,请你向刘备学习,为你自己输出三行"Accepted 13 Problems."

输入描述:

本题没有输入

输出描述:

请输出三行"Accepted 13 Problems."

样例输入

样例输出

Accepted 13 Problems.

Accepted 13 Problems.

Accepted 13 Problems.

代码如下:

#include<iostream>

using namespace std;

int main(){
	printf("Accepted 13 Problems.\nAccepted 13 Problems.\nAccepted 13 Problems.");
	return 0;
}

7.诸葛亮草船借箭 

题目链接:https://nwanna.cn/problems/ZJYYC1321

题目描述:


现在周瑜又给诸葛亮出了一个难题,由于曹操的弓兵所装备的箭分为三个不同的种类:分别为锥形箭、破甲箭和重箭。现在已知诸葛亮的N条草船是按1~N的顺序在江面上排列的。现在周瑜随便给出一个箭的种类,然后再给出两艘草船的编号,请诸葛亮迅速说出这两艘草船以及它们之间的所有草船上该种类的箭一共有多少。现在,诸葛亮把这个难题丢给你了,希望你能迅速解决掉它。

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入一个正整数N(1 <= N <= 50000)代表诸葛亮的草船数量。接下来三行,第一行输入N个正整数Ni(0 <= Ni <= 50000)代表每搜草船上锥形箭的数量,第二行输入N个正整数Nj(0 <= Nj <= 50000)代表每搜草船上破甲箭的数量,第三行输入N个正整数Nk(0 <= Nk <= 50000)代表每搜草船上重箭的数量。然后第四行输入一个正整数M(1 <= M <= 10000),代表周瑜的询问数量。接下来M行,每行输入一个字符串 str(str具体值请看下面的例子) 和两个数字a和b(1 <= a,b <= N),分别代表询问的箭的类型以及两艘草船的编号。

注意:str的值只可能是以下三种:ZHUIXING、POJIA、ZHONG,分别代表锥形箭、破甲箭和重箭

输出描述:

对于每组测试样例,输出M行,每行输出对于周瑜当前询问的统计结果。

样例输入

3

1 2 3

2 2 2

1 2 3

3

POJIA 1 3

ZHONG 3 3

ZHUIXING 1 2

样例输出

6 3 3

解题心得:

简单的前缀和即可。头脑第一反应是树状数组就直接用了。

代码如下:

#include<iostream>
#include<cstring>

using namespace std;

typedef long long ll;
const int N = 5E4 + 5;
#define lowbit(x) x & (-x)

ll tree[N][5];
int n;
 
inline void update(int i, int x, int f){
	for(int pos = i; pos <= n; pos += lowbit(pos))	tree[pos][f] += x;
}

inline ll query(int i, int f){
	ll ans = 0;
	for(int pos = i; pos; pos -= lowbit(pos))	ans += tree[pos][f];
	return ans;
}

int main(){
	while(cin>>n){
		memset(tree, 0, sizeof tree);
		for(int i = 1; i <= 3; i ++ ){
			for(int j = 1; j <= n; j ++ ){
				int x;
				cin>>x;
				update(j, x, i);
			}
		}
		int q;
		cin>>q;
		while(q -- ){
			string s;
			int l, r;
			cin>>s>>l>>r;
			if(l > r)	swap(l, r);
			if(s == "POJIA")	cout<<query(r, 2) - query(l - 1, 2)<<'\n';
			if(s == "ZHONG")	cout<<query(r, 3) - query(l - 1, 3)<<'\n';
			if(s == "ZHUIXING")	cout<<query(r, 1) - query(l - 1, 1)<<'\n';
		}
	}
	return 0;
}

8.吕奉先辕门射戟 

题目链接:https://nwanna.cn/problems/ZJYYC1323

题目描述:


现在吕布又在练习他的箭法。他摆了一排的箭靶,每个箭靶上都有一个分数,吕布命中一个箭靶就能获得箭靶上对应的分数。吕布射箭有一个习惯,他不喜欢连续往相邻的箭靶上射箭。比如吕布第一次对着1号箭靶射了一箭,那么吕布在后面的射箭中,都不会再往2号箭靶上射箭。现在吕布从1号箭靶开始,对于每个箭靶,吕布可以选择射箭或者不射箭,现在请问吕布最多能够获得多少分数?(吕布作为三国第一猛将,箭法自然是百发百中)

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入一个正整数N(1 <= N <= 100000)代表箭靶的数量。接下来一行,输入N个整数Ni(0 <= Ni <= 10000)分别代表每个箭靶上对应的分数。

输出描述:

对于每组测试样例,输出吕布能够获得的最高分数。

样例输入

5

1 2 3 4 5

样例输出

9

解题心得:

a[i]第i号靶的分数。

f[i] :第1号靶射到第i号靶的最高分数。

DP问题。由题意可推出动态转移方程f[i] = max(f[i - 1], f[i - 2] + a[i]);

代码如下:

#include<iostream>

using namespace std;

const int N = 1e5 + 5;

int t;
int f[N], a[N];

int main()
{
	while(cin>>t){
		int val = 0;
		for(int i = 1; i <= t; i ++ )	cin>>a[i];
		f[1] = a[1];
		f[2] = max(a[1], a[2]);
		for(int i = 3; i <= t; i ++ )	f[i] = max(f[i - 1], f[i - 2] + a[i]);
		cout<<f[t]<<'\n';
	}
	return 0;
}


9. 姜伯约北伐中原

题目链接:https://nwanna.cn/problems/ZJYYC1319

题目描述:


现在姜维仍然想北伐中原,光复汉室,但是他现在需要一个人帮他统计一下。现在姜维率领的蜀汉军队中,士兵都有一个能力值。如果一个士兵的能力值在1~10的话,则是新兵。如果一个士兵的能力值在11~20的话,则是老兵。如果一个士兵的能力值在21~30的话,则是百战精兵。现在姜维想请你替他统计一下,现在的蜀汉军队中,新兵、老兵以及百战精兵的人数。

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入一个正整数N(1 <= N <= 10000),代表姜维率领的蜀汉军队中士兵的数量。第二行输入N个正整数Ni(1 <= Ni <= 30),代表第i个士兵的能力值。

输出描述:

对于每组测试样例,按照新兵、老兵、百战精兵的顺序输出对应的士兵人数

样例输入

5

10 15 20 6 21

样例输出

2 2 1

解题心得:

模拟即可。

代码如下:

#include<iostream>
#include<cstring>

using namespace std;

const int N = 5;

int f[N];

int main(){
	int t;
	while(cin>>t){
		f[0] = f[1] = f[2] = 0;
		for(int i = 1; i <= t; i ++ ){
			int x;
			cin>>x;
			if(x >= 1 && x <= 10)	f[0] ++;
			else if(x >= 11 && x <= 20)	f[1] ++;
			else if(x >= 21 && x <= 30)	f[2] ++;	
		}
		cout<<f[0]<<" "<<f[1]<<" "<<f[2]<<'\n';
	}
	return 0;
}

10.曹孟德青梅煮酒 

题目链接:https://nwanna.cn/problems/ZJYYC1320

题目描述:

煮酒论英雄是中国古代四大名著《三国演义》中的一个片段。指建安四年袁绍曹操官渡之战前,掌控朝局的曹操以酒宴试探刘备是否有称霸天下的野心,最终被刘备巧言瞒过的故事。现在曹操约你一块青梅煮酒,他给了你一份天下能人异士的名单,名单上记载了每位能人异士的姓名、武力值、智力值。现在曹操希望你按照以下规则给他列出一份武将榜和一份谋士榜,规则如下:


武将榜:对于每位能人异士,按照武力值从高到低排序,如果武力值相同,则按照智力值从高到低排序,如果智力值相同,则按姓名字典序从小到大排序

谋士榜:对于每位能人异士,按照智力值从高到低排序,如果智力值相同,则按照武力值从高到低排序,如果武力值相同,则按姓名字典序从小到大排序

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入一个正整数N(1 <= N <= 100000),代表名单上能人异士的数量。接下来N行,每行输入一个字符串str(1 <= str.length <= 10)和两个整数a和b(0 <= a,b <= 120),分别代表每位能人异士的姓名、武力值和智力值。

输出描述:

对于每组测试样例,首先按照排名、姓名、武力值和智力值的顺序依次输出武将榜。接下再按照相同的顺序,依次输出谋士榜。在武将榜和谋士榜之间,使用一个空行进行分隔。


注意:如果榜单上的两位能人异士武力值和智力值相同,则排名应该相同。

样例输入

10

zhangfei 99 56

machao 100 50 l

vbu 110 23

zhugeliang 18 100

guojia 12 110

jiangwei 93 90

zhaoyun 93 90

luxun 78 95

xiahouyuan 97 36

pangtong 18 100

样例输出

1 lvbu 110 23

2 machao 100 50

3 zhangfei 99 56

4 xiahouyuan 97 36

5 jiangwei 93 90

5 zhaoyun 93 90

7 luxun 78 95

8 pangtong 18 100

8 zhugeliang 18 100

10 guojia 12 110

1 guojia 12 110

2 pangtong 18 100

2 zhugeliang 18 100

4 luxun 78 95

5 jiangwei 93 90

5 zhaoyun 93 90

7 zhangfei 99 56

8 machao 100 50

9 xiahouyuan 97 36

10 lvbu 110 23

解题心得:

就是对sort排序的运用。

代码如下:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 1e5 + 5;

struct mxd{
	string s;
	int wl, zl;
}f[N];

bool cmp1(mxd a, mxd b){
	if(a.wl == b.wl){
		if(a.zl == b.zl)	return a.s < b.s;
		return a.zl > b.zl;
	}
	return a.wl > b.wl; 
}

bool cmp2(mxd a, mxd b){
	if(a.zl == b.zl){
		if(a.wl == b.wl)	return a.s < b.s;
		return a.wl > b.wl;
	}
	return a.zl > b.zl;
}

int main(){
	int n;
	while(cin>>n){
		for(int i = 1; i <= n; i ++ )	cin>>f[i].s>>f[i].wl>>f[i].zl;
		sort(f + 1, f + n + 1, cmp1);
		int id = 1;
		cout<<id<<" "<<f[1].s<<" "<<f[1].wl<<" "<<f[1].zl<<'\n';
		for(int i = 2; i <= n; i ++ ){
			if(f[i].wl == f[i - 1].wl && f[i].zl == f[i - 1].zl)
				cout<<id<<" "<<f[i].s<<" "<<f[i].wl<<" "<<f[i].zl<<'\n';
			else{
				id = i;
				cout<<i<<" "<<f[i].s<<" "<<f[i].wl<<" "<<f[i].zl<<'\n';
			}
			
		}
		cout<<'\n';
		sort(f + 1, f + n + 1, cmp2);	
		id = 1;
		cout<<id<<" "<<f[1].s<<" "<<f[1].wl<<" "<<f[1].zl<<'\n';
		for(int i = 2; i <= n; i ++ ){
			if(f[i].wl == f[i - 1].wl && f[i].zl == f[i - 1].zl)
				cout<<id<<" "<<f[i].s<<" "<<f[i].wl<<" "<<f[i].zl<<'\n';
			else{
				id = i;
				cout<<i<<" "<<f[i].s<<" "<<f[i].wl<<" "<<f[i].zl<<'\n';
			}
		}	
	}
	return 0;
}

11.陆伯言火烧连营 

题目链接:https://nwanna.cn/problems/ZJYYC1302

题目描述:


由于火烧连营消耗的火球太多,于是陆逊分配给你一个任务。有n个火球组成的火球序列,你可以通过增减火药的方式将序列中的一个火球的重量变为序列中另外两个不同火球的重量之和。对于每个火球,你都可以选择改变或者不改变。由于火球需要便携,所以需要使所有火球重量都小于等于m。你能解决这个问题吗?

输入描述:

题目包含多组测试样例。对于每组数据第一行输入两个整数n(3 <= n <= 1000)、m(1 <= m <= 1e8)分别代表火球的数量和每个火球允许的最大重量。第二行输入n个正整数ni(1 <= ni <= 1e6)分别代表每个火球的初始重量。

输出描述:

对于每组测试样例,如果最后火球重量都可以小于等于m,则输出JianJianDanDan, 反之输出BuBuBu。

样例输入 1

3 88 70 99 71

样例输出 1

BuBuBu

样例输入 2

3 75 78 19 22

样例输出 2

JianJianDanDan

解题心得:

只需得知最小的两个数是否大于m即可。

代码如下:

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1005;

int n, m;
int f[N];

int main(){
	while(cin>>n>>m){
		for(int i = 0; i < n; i ++ )	cin>>f[i];
		sort(f, f + n);
		if(n >= 3 && f[0] + f[1] > m)	cout<<"BuBuBu\n";
		else	cout<<"JianJianDanDan\n";
	}
	return 0;
}

12.关云长千里单骑 

题目链接:https://nwanna.cn/problems/ZJYYC1322

题目描述:


现在我们有一份N*M的地图,地图的方向是传统的上北下南左西右东,地图由以下字符组成:
大写字母G代表关羽的初始位置
大写字母L是刘备的所在位置
字符.代表普通的道路
数字1~9代表此处有曹魏武将镇守


我们手上除了地图以外,还有一份关羽的千里走单骑的指令集,指令集是一个字符串,由以下字符组成:
大写字母N,代表关羽向北走一步
大写字母E,代表关羽向东走一步
大写字母S,代表关羽向南走一步
大写字母W,代表关羽向西走一步


关羽在走单骑的规则如下:
1.关羽将根据指令集的顺序进行行动,每执行一个指令,需要花费一天的时间
2.关羽在普通道路上(含关羽的初始位置和刘备的位置)行走一步需要消耗体力值1点
3.关羽如果经过曹魏武将镇守之地,则会与曹魏武将发生战斗(战斗会在瞬间完成),需要消耗当前曹魏武将对应数值的体力值
4.如果关羽的体力值不足以下一次行走或者挑战曹魏武将时,会暂停执行该指令停留在原地休息,休息期间每一天会恢复1点体力值,直到关羽能够再次行动为止(如果恰好停留在曹魏武将的镇守关卡上,不会再次触发战斗)
5.如果下一次的指令会使得关羽走出地图之外,那么关羽也会原地休息一天并且跳过该指令


现在请问根据关羽千里走单骑的路线,关羽能够遇见自己的主公刘备吗?现在请擅长编程的你,帮助关羽计算一下。

输入描述:

测试样例由多组测试数据组成。对于每组测试数据,第一行输入两个正整数N和M(2 <= N,M <= 100),代表地图的大小。接下来输入一个N*M的矩阵,再接着输入一个字符串str(1 <= str.length <= 1000)和一个整数number(0 <= number <= 100)分别代表关羽的行走路线和关羽的初始体力。

输出描述:

对于每组测试数据。如果按照关羽的行走路线,关羽能够碰见刘备,则在第一行输出YES,紧跟着一行输出关羽遇见刘备所经过的天数。如果关羽执行完指令也没有遇见刘备,则输出NO

样例输入

5 5

G...L

5.3..

.....

2.4.6

...5.

EEEE 5

样例输出

YES

4

解题心得:

被题目恶心坏了。首先根据题意模拟一下即可,但是要注意坑。即经过曹魏武将镇守之地时,是不消耗体力1点的。后面有wa的代码。

AC代码如下:

#include<iostream>
#include<cstring>
#include<unordered_map>
 
using namespace std;

const int N = 105;

string op;	//指令 
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
char g[N][N];
int n, m;
int x, y, hp;//关羽位置,体力 

unordered_map<char,int>mp{{'N',3},{'E',0},{'S',1},{'W',2}};

int solve(){	
	int tian = 0;
	for(int i = 0; i < op.size(); i ++ ){
		char c = op[i];
		int a = dx[mp[c]] + x, b = dy[mp[c]] + y;
		if(a < 1 || a > n || b < 1 || b > m){
			tian ++;
			hp ++;
			continue;
		}
		else if(g[a][b] == 'G' || g[a][b] == '.'){
			if(hp > 0)	hp --, tian ++;
			else	tian += 2;
		}
		else if(g[a][b] == 'L'){
			if(hp > 0)	return tian + 1;
			else	return tian + 2;
		}
		else if(g[a][b] >= '1' && g[a][b] <= '9'){
			int val = g[a][b] - '0';
			int rest_hp = hp - val;
			if(rest_hp >= 0)	hp = rest_hp, tian ++;
			else	tian += abs(rest_hp) + 1, hp = 0;
		}
		x = a, y = b;
	}
	return -1; 
}

int main(){
	while(cin>>n>>m){
		for(int i = 1; i <= n; i ++ )
			for(int j = 1; j <= m; j ++ ){
				cin>>g[i][j];
				if(g[i][j] == 'G')	x = i, y = j;
			}
		cin>>op>>hp;
		int	val = solve();
		if(val == -1)	cout<<"NO\n";
		else	cout<<"YES\n"<<val<<'\n';
	}	
	return 0;
}

WA代码如下qaq:

#include<iostream>
#include<cstring>
#include<unordered_map>
 
using namespace std;

const int N = 105;

string op;	//指令 
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
char g[N][N];
int n, m;
int x, y, hp;//关羽位置,体力 

unordered_map<char,int>mp{{'N',3},{'E',0},{'S',1},{'W',2}};

int solve(){	
	int tian = 0;
	for(int i = 0; i < op.size(); i ++ ){
		char c = op[i];
		int a = dx[mp[c]] + x, b = dy[mp[c]] + y;
		if(a < 1 || a > n || b < 1 || b > m){
			tian ++;
			hp ++;
			continue;
		}
		if(g[a][b] == 'G' || g[a][b] == '.'){
			if(hp > 0)	hp --, tian ++;
			else	tian += 2;
		}
		if(g[a][b] == 'L'){
			if(hp > 0)	return tian + 1;
			else	return tian + 2;
		}
		if(g[a][b] >= '1' && g[a][b] <= '9'){
			int val = g[a][b] - '0';
			if(hp > 0){
				hp --;
				tian ++;
				if(hp > val)	hp -= val;
				else if(hp == val)	hp = 1, tian ++; 
				else	tian += val - hp, hp = val;
			}else{
				/*
				hp ++;
				tian ++;
				hp --;
				tian ++;
				hp ++;
				tian ++;
				*/
				hp = 1, tian += 3;
			}
		}
		x = a, y = b;
		//cout<<"tian = "<<tian<<'\n';
	}
	return -1; 
}

int main(){
	while(cin>>n>>m){
		for(int i = 1; i <= n; i ++ )
			for(int j = 1; j <= m; j ++ ){
				cin>>g[i][j];
				if(g[i][j] == 'G')	x = i, y = j;
			}
		cin>>op>>hp;
		int	val = solve();
		if(val == -1)	cout<<"NO\n";
		else	cout<<"YES\n"<<val<<'\n';
	}	
	return 0;
} 
/*
5 5
G...L
1234.
.....
.....
.....
SEEEENES 0
*/

13.黄月英奇门遁甲 

题目描述:


现在黄月英准备了两副木牌序列并且排列完成,木牌上的数字为0~9之间的任意一个整数。现在黄月英想让你从两副木牌序列中选出K张木牌,拼接组成一个新的数字,要求这个数字最大并且保持着原先在木牌序列中的相对顺序。你能解决一下这个问题嘛?如果你能成功解决,说不定你就是下一个精通奇门遁甲之人!

输入描述:

测试样例由多组测试数据组成。每组测试数据第一行输入两个正整数 n 和 m (1 <= n,m <= 1000),分别代表两个木牌序列的木牌数量。接下来两行,分别输入n个整数和m个整数,代表每张木牌上的数字(由0~9组成),最后一行输入一个正整数 K (1 <= K <= n + m),代表你需要选出的木牌数量。

输出描述:

对于每组测试数据,输出你能够挑出K张木牌组成的最大数字。

样例输入 1

2 3

6 4

9 0 1

4

样例输出 1

9641

样例输入 2

5 5

1 2 3 4 5

5 4 3 2 1

5

样例输出 2

55432

代码如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值