“卓见杯”郑州轻工业大学2020级新生程序设计大赛

2779: 小A与泉水

题目描述
小A遇到了一座神奇的泉水,在泉水中洗涤会大幅增加他的精力。在一次洗涤中,泉水增加力量的数值为当前力量二进制表示中的最低位的1对应的值。
例如:
如果当前力量为9(1001 最低位1对应的值为1),增加的力量为1;
如果当前力量为12(1100 最低位1对应的值为100),增加的力量为4。
小A想要将他的力量变为2的幂次数,他需要在泉水中洗涤多少次呢?

输入
多样例测试
第一行输入T(T<=100,000),代表样例数;
剩余T行,每行输入一个数n(n<1,000,000,000)代表小A当前的力量。

输出
对于每次询问,输出小A需要在泉水中洗涤的次数。

样例输入
4
1
2
3
5
样例输出
0
0
1
2

这题在oj上用cin,cout会被卡。熟悉二进制会很容易写出来。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int jud(ll n){
    
    
	int ans = 0;
	while(n > 1){
    
    
		if(n%2 == 1){
    
    
			ans++; n++; n=n/2;
		}else n = n/2;
	}
	return ans;
}
int main(){
    
    
	ll t, a;
	scanf("%lld",&t);
	while(t--){
    
    
		scanf("%lld",&a);
		printf("%d\n",jud(a));
	}
}

2780: 小A的宝藏

题目描述
小A和小B历经千辛万苦,终于在一个洞穴中找到了宝藏。
在洞穴深处,他们发现了一颗价值连城的宝石,他们决定做一个游戏以决定宝石属于谁。
游戏规则如下:
每人在自己的回合必须选择其中一个操作:
1.拿走一块或者两块银子;
2.拿走一块金子。
无法继续进行操作的人被认为失败(即银子和金子都已经拿完)。
谁将得到宝石呢?

输入
多样例测试
第一行输入T(T<=100,000),代表样例数;
剩余T行,每行输入n,m(n<1,000,000,000,m<1,000,000,000) 代表银子和金子的数量。

输出
如果小A胜利,输出"Alice",否则输出"Bob"。

样例输入
3
1 0
3 0
3 1
样例输出
Alice
Bob
Alice

博弈论,分析一下必胜情况与必败情况,就可以发现规律。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    
    
	ll t, m, n;
	scanf("%lld",&t);
	while(t--){
    
    
		scanf("%lld%lld",&n,&m);
		if(m%2 == 0){
    
    
			if(n%3 == 0) printf("Bob\n");
			else printf("Alice\n");
		}else {
    
    
			if((n-1)%3 == 0) printf("Bob\n");
			else printf("Alice\n");
		}
	}
}

2781: 小A的魔法

题目描述
小A踏上了AK这场新生赛的旅程。但对方太狡猾,将小A传送到了一个不知名的地方。经过探查,小A发现了一座很大的迷宫。这座迷宫从上方看竟然是正方形的,而且内部被分为了1个同等大小房间,而狡猾的敌人则隐藏在某些房间中,准备偷袭小A.
幸好小A提前发现了对方的阴谋,准备解决所有的敌人。但敌人太多了,小A准备使用高级魔法—“这题我会”。这个魔法的作用范围是正好是一个矩形,能够覆盖W∗H个房间(注意:W∗H与H∗W是不同的,如:2 * 3与3 * 2是两种魔法),处于该范围内的敌人将会被魔法消灭魔法的边界必须与房间的墙壁重合,否则狡猾的敌人会躲在墙边,从而躲开此次攻击。小A只能发动一次该魔法,他希望魔法发动时能攻击到更多的敌人。小A选择寻求你的帮助,他告诉你了n个敌人的位置,你能告诉他,发动魔法最多能消灭多少个敌人吗?
例如:小A魔法的范围是3*2,他共探查到了5个敌人,位置如下,他最多可以消灭4个敌人。

输入
第一行包含3个整数n, W, H(1<= n <= 100, 1<= W, H<= 1000)。代表共有n个敌人,魔法的打击范围是W*H。

接下来n行,每行包含两个整数x_i, y_i(1<= x_i, y_i <= 1000), 代表第i个敌人位于坐标(xi, yi)的房间。保证每个房间最多只有一个敌人。

输出
输出一个整数。代表小A发动魔法,最多消灭的敌人的数量。
样例输入
5 3 2
1 1
2 1
3 1
4 1
4 2
样例输出
4

二维前缀和

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int arr[1005][1005];
int dp[1005][1005];
int main(){
    
    
	int n, w, h, a, b, ans = 0;
	cin >> n >> w >> h;
	for(int i = 0; i < n; i++){
    
    
		cin >> a >> b;
		arr[a][b] = 1;
	}
	for(int i = 1; i <= 1000; i++){
    
    
		for(int j = 1; j <= 1000; j++){
    
    
			dp[i][j] = dp[i-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1];
		}
	}
	for(int i = w; i <= 1000; i++){
    
    
		for(int j = h; j <= 1000; j++){
    
    
			ans = max(ans, dp[i][j]-dp[i-w][j]-dp[i][j-h] + dp[i-w][j-h]);
		}
	}
	cout << ans;
}

2782: 靶场射击2.0

题目描述
“欢迎来到靶场射击2.0.”
小A正在挑战一款叫做《靶场射击2.0》的游戏。游戏内共有两种靶子,一种是金色靶子,击中可以获得a积分,一种是普通靶子,击中可以获得b积分(a≥b)。每个靶子上都有一个字母,金色靶子上的为大写字母,普通靶子上的为小写字母。
当按下按键时,能得到所有对应字母相同的靶子的积分。如"WWWAAaa",按下键’A’,则能得到2∗a+2∗b积分,按下键’W’,则能得到3∗a积分。
小A想挑战点不一样的,他想知道当前局面,按哪个键能得到的积分最多。

输入
第一行包含三个整数n,a,b(1<=n<=100000,1≤b≤a≤10),代表n代表靶子数量,击中金色靶子获得的积分,击中普通靶子获得的积分。
第二行有n个字母,代表当前n个靶子上的字母。其中大写字母代表金色靶子,小写字母代表普通靶子。

输出
输出一个大写字符。代表小新按下该字符,能得到最多的积分。若有多个按键可以得到相同的积分,则输出字典序最小的那个字符。

样例输入
7 3 2
WWWAAaa

样例输出
A

将26个字母带进去,枚举一遍,最大的就是答案。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
string str;
int n, a, b;
ll jud(char c){
    
    
	ll ans = 0;
	for(int i = 0; i<str.size(); i++){
    
    
		if(str[i] == c ){
    
    
			ans += a;
		}else if(str[i]  == c+32){
    
    
			ans += b;
		}
	} 
	return ans;
}
int main(){
    
    
	cin >> n >> a >> b;
	cin >> str;
	char ans;
	ll num = -1;
	for(char i = 'A'; i<='Z'; i++){
    
    
		ll sum = jud(i);
		if(sum > num){
    
    
			num = sum; ans = i;
		}
	}
	cout << ans;
} 

2783: 魔法药水

题目描述
小A终于来到了最后一题。小明翻找自己的背包,发现了很多能够提升自己能力值的药水。小A共发现了n种药水,第i种药水有ai瓶,使用后能使能力值加bi。但相同种类的药水,是不能连续使用的。小A觉得自己至少将能力值提升X(X>=1),才有把握AK这场新生赛。药水的味道并不好,小明想尽量少的使用药水。你能告诉小A,他至少使用多少瓶药水, 才能使自己的能力提升至少X?

输入
第一行包含两个整数n,X(1≤n≤1000,1≤X≤10,000,000,000,000,000); 接下来n行,每行包括两个整数ai,bi(1≤ai,bi≤10,000,000),代表第i种药水有ai瓶,使用后能提示能力值bi。

输出
如果小A不能使自己的能力提升至少X,输出“-1”;否则输出小A最少使用的药水的数量。

样例输入
2 1000
10 200
5 1

样例输出
9

贪心? 二分?反正还不会写。

2784: 代码格式化

题目描述
学弟给了学长一份代码,让学长帮忙debug,可是这段代码却是这样的:

#include<stdio.h>
int main(){int a,b;int c=a+b;printf(“Hello world!\n”);return 0;}

这段代码机器能看懂,但是学长看不懂。
这代码有两个问题:没有换行缩进,二元运算符附近没有空格。
显然这是一段未格式化的代码,将其格式化成符合要求的格式。花括号不包含嵌套的情况。
格式要求:

  1. 需要换行
  2. 四个空格作为一个缩进单位
  3. 花括号{不换行,跟在前一个语句之后,但是隔开一个空格。
  4. 二元运算符周围没有放空格,因为学弟的代码只包含=,+,-,*,/,%这六个二元运算符

格式化后的代码:

#include<stdio.h>
int main() {
int a,b;
int c = a + b;
printf(“Hello world!\n”);
return 0;
}

输入
两行可以编译的但是格式不符合的要求的代码,一行为头文件(保证只有一个头文件),一行为主函数代码。代码的问题如上所述,代码长度小于1000。代码中的花括号只包含主函数中的一对。保证代码主函数中有语句。
注意:代码中不包含多余的分号。printf函数内不会出现花括号和二元运算符

输出
满足格式格式要求的代码

样例输入

#include<stdio.h>
int main(){
    
    int a, b;a=9900,b=99;int c=a+b;int d=1,e;int ans=a+b+c/d%a*a-89+e;return 0;}

样例输出

#include<stdio.h>
int main() {
    
    
    int a, b;
    a = 9900,b = 99;
    int c = a + b;
    int d = 1,e;
    int ans = a + b + c / d % a * a - 89 + e;
    return 0;
} 

对字符串的处理。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    
    
	string str1, str2;
	cin >> str1; getchar();
	getline(cin, str2);
	cout << str1 << endl;
	for(int i = 0; i < str2.size(); i++){
    
    
		cout << str2[i];
		if(str2[i+1] == '{'){
    
    
			cout << " ";
		}
		if(str2[i+1] == '+' ||str2[i+1] == '-' || str2[i+1] == '*'
		|| str2[i+1] == '=' || str2[i+1] == '/' || str2[i+1] == '%'){
    
    
			cout << " ";
		}
		if(str2[i] == '{' || str2[i] == ';' && str2[i+1] != '}'){
    
    
			cout << "\n    ";
		}else if(str2[i] == ';' && str2[i+1] == '}'){
    
    
			cout << "\n";
		}else if(str2[i] == '+' ||str2[i] == '-' || str2[i] == '*'
		|| str2[i] == '=' || str2[i] == '/' || str2[i] == '%'){
    
    
			cout << " ";
		}
	}
}

2785: 贪心的小H

题目描述
小H是一个考古学家,有一天他发现了海盗的宝藏,但是他只带了一个背包。现在摆在面前的宝物有100多件,每个宝物都有一个类型值(type)和一个珍贵程度(value)。现在要求选择若干个宝物(可以是0个)放进背包使得x * y最大,x为选择的不同type的数量,y为总的value值之和(同一种宝物value值一致,只计算一次value值)

输入
第一行输入一个整数n表示物品的数量(1 ≤ n ≤ 200)
第二行输入n个整数type_i表示每个物品的类型(1 ≤ type_i ≤ 200)
第三行输入n个整数value_i(-100000 ≤ value_i ≤ 100000)

输出
输出一个整数

样例输入
2
1 2
4 7
样例输出
22

排个序后按题意贪心就行。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
    
    
	int t, v;
}arr[300];
int n, a, b;
map<int, int>mp;

bool cmp(node a, node b){
    
    
	return a.v > b.v;
}
int arr1[300], arr2[300];
int main(){
    
    
	cin >> n;
	for(int i = 0; i<n; i++) cin >> arr1[i];
	for(int i = 0; i<n; i++) cin >> arr2[i];
	for(int i = 0; i<n; i++){
    
    
		//map用来去重
		mp[arr1[i]] = arr2[i];
	}
	int f = 0;
	for(map<int ,int>::iterator it = mp.begin(); it != mp.end(); it++){
    
    
		int n1 = it->first, n2 = it->second;
		arr[f].t = n1, arr[f++].v = n2;
	}
	sort(arr, arr+f, cmp);
	//贪心
	ll ans = 0, t = 0, v = 0;
	for(int i = 0; i < f; i++){
    
    
		if((t+1)*(v+arr[i].v) >= ans){
    
    
			t++; v = v+arr[i].v;
			ans = t*v;
		}
	}
	cout << ans;
	
}

2786: 这是一道数学题

题目描述
一个数通过最小次数交换数位变成20的倍数。问最少交换次数是多少?

输入
一个正整数T(1<=T<=200),代表有T组输入。每个输入包含一个正整数N(1<=N<=10的18次方),N没有前导0。

输出
最小的交换次数。如果不能交换出20的倍数,输出-1

样例输入
2
70007
680
样例输出
1
0

可以发现,只有-1,0,1,2四种答案,能被20整除,证明数中必须要有一个0,和一个偶数,没有的话就是答案是-1。有的话根据这个数后两位的情况判断需要几次。写的有点麻烦了,懒得精简了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int jud(char c){
    
    
	return (c-'0') % 2;
}

int main(){
    
    
	int t, int arr[10];
	cin >> t;
	while(t--){
    
    
		memset(arr,0,sizeof(arr));
		string str;
		int ans = 0;
		cin >> str;
		for(int i = 0 ;i<str.size(); i++){
    
    
			arr[str[i]-'0']++;
		}
		if(arr[0] == 0) ans = -1;
		else{
    
    
			arr[0]--;
			for(int i = 0; i < 10; i=i+2){
    
    
				if(arr[i] != 0) ans = 2;
			}
			if(ans == 2){
    
    
				if(str[str.size()-1] == '0') ans--;
				if(arr[0] >= 1){
    
    
					if(jud(str[str.size()-2]) == 0) ans--;
				}else{
    
    
					if(jud(str[str.size()-2]) == 0 && str[str.size()-2]!='0') ans--;
				}
			}else	ans = -1;
		}
		if(jud(str[str.size()-1]) == 0 && str[str.size()-2] == '0')
			ans = 1;
		if(str[str.size()-1] == '0' && str[str.size()-2] == '0')
			ans = 0;
		cout << ans << endl;
	}
}

2787: 小A的魔力

题目描述
众所周知,小A学长是郑轻全能王,新来的学弟学妹们都特别崇拜小A学长,大家在每次比赛前都会摸一摸小A学长,为自己祈福。新生赛即将来临,n名同学为了能够获得更好的成绩,纷纷来找小A学长讨教算法并得到学长的祝福,小A学长为第i名学生辅导a_i分钟。小A学长有一项神奇的本领,为任意两名同学辅导的时间都不相同。小A学长会认为被辅导时间最长的同学将获得冠军,但是小A学长忙于辅导同学,没有时间计算谁会获得冠军,小A学长希望你帮他算一下。

输入
输入第一行包含一个整数n(1<=n<=5000),代表被小A学长辅导的同学的个数。接下来n行,每行包含一个字符串s(1<=len(s)<=20)和一个正整数(int范围内),分别代表学生的姓名和被辅导的时长。

输出
输出将会获得冠军的学生的姓名。

样例输入
4
Bob 20
William 46
Mark 8
Bill 10
样例输出
William

遍历一遍找最大的数,并用一个字符串记录就行。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main(){
    
    
	string s, ans;
	int n, m, maxm;
	cin >> n;
	for(int i = 0; i<n; i++){
    
    
		cin >> s >> m;
		if(m > maxm){
    
    
			maxm = m; ans = s;
		}
	}
	cout << ans;
}

2788: define int long long

题目描述
小A和队友一起比赛时,偷偷的加了一句"#define int long long"。导致队友wrong answer了三个小时。赛后被队友发现,小A的队友为了惩罚小A,决定让他抄2147483647遍"#define int long long"。绝望的小A希望你能帮他抄写10遍,你能帮帮他吗?

输入

输出
输出10遍"#define int long long"。

样例输出
#define int long long
#define int long long
#define int long long
#define int long long
#define int long long
#define int long long
#define int long long
#define int long long
#define int long long
#define int long long

签到使我快乐。

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    
	for(int i = 0; i<10; i++){
    
    
		cout << "#define int long long" << endl; 
	}
}

猜你喜欢

转载自blog.csdn.net/qq_45874814/article/details/115185844