哈尔滨理工大学软件与微电子学院程序设计竞赛 题解

好的,没错,是我,我又来水博客了!

A 抗疫必胜1(水题)

题目描述

2020年,抗击疫情,众志成城,我们一定能取得疫情战役最后的胜利(Victory)。乎乎想用大写字母V组成大V,请帮他编程实现。

输入描述:

输出描述:

V     V
 V   V
  V V
   V
signed main() {
 	printf("V     V\n");
 	printf(" V   V\n");
 	printf("  V V\n");
 	printf("   V");
 	return 0;
}

B 疫情死亡率 (水题)

题目描述

请根据各国报告的疫情确诊数和死亡数,计算新冠疫情在各国的死亡率。

输入描述:

输入仅一行,有两个整数(范围 [ 1 , 2 31 − 1 ] [1 ,2^{31}-1] [1,2311] ),第一个为确诊数,第二个为死亡数。

输出描述:

输出仅一行,甲流死亡率,以百分数形式输出,精确到小数点后3位。

输入

10433 280

输出

2.684%

求百分率

signed main() {
 	int n = read(), m = read();
 	double res = 0;
 	res = 1.0 * m / n;
 	printf("%.3lf%\n", res * 100);
 	return 0;
}

C 整除判断 (水题)

题目描述

乎乎学会了除法,他想知道整数m能否被整数n整除。

输入描述:

输入仅一行,有两个整数(范围 [ 1 , 2 31 − 1 ] [1 ,2^{31}-1] [1,2311]),第一个为m,第二个为n。

输出描述:

输出仅一行,m 能被 n 整除输出 YES,否则输出 NO

输入

36 6

输出

YES
signed main() {
 	int n = read(), m = read();
 	if (n % m == 0) printf("YES\n");
 	else printf("NO\n");
 	return 0;
}

D 编程时间 (水题)

题目描述

疫情期间,乎乎学习了程序设计基础,他很爱编程,他给自己的编程时间做了精确的计时(本题中的计时都按24小时制计算),它发现自己从h1时m1分一直编程到当天的h2时m2分,请你帮乎乎计算一下,它这天一共编程了多少时间呢?
输入描述:

一行,输入 4 个整数,分别表示 h1, m1, h2, m2,用空格隔开。

输出描述:

一行,输出 2 个整数 h3 和 m3,用空格间隔,依次表示乎乎这天一共编了多少小时多少分钟。其中表示分钟的整数 m3应该小于60。

输入

12 50 19 10

输出

6 20
signed main() {
 	int h1 = read(), m1 = read(), h2 = read(), m2 = read();
 	int h3 = 0, m3 = 0;
 	h3 = h2 - h1;
 	if (m1 > m2) {
 		h3--;
 		m3 = 60 - m1 + m2;
	} else {
		m3 = m2 - m1;
	}
 	printf("%lld %lld\n", h3, m3);
 	return 0;
}

E 中奖情况 (水题)

题目描述
乎乎最近迷上买“双位彩”,彩票的获奖号码由两位非零数组成,中奖规则如下:

如果乎乎买的彩票号码和中奖号码完全相同,奖金为100元;

如果乎乎买的彩票号码仅能匹配中奖号码的所有数字,奖金为20元;

如果乎乎买的彩票号码仅能匹配中奖号码的一个数字,奖金为2元。

输入描述:
一行,输入两个两位整数,分别表示获奖号码和乎乎买的彩票号码(范围11~99) 。
输出描述:
一行,一个整数,表示获奖奖金。

输入

86 68

输出

20

备注:
提示:需要考虑没有中奖的情况。

signed main() {
 	int n = read(), m = read();
 	int a, b, c, d;
 	a = n / 10;
 	b = n % 10;
 	c = m / 10;
 	d = m % 10;
 	if (a == c && b == d) printf("100\n");
 	else if (a == d && b == c) printf("20\n");
 	else if (a == c || b == d || a == d || b == c) printf("2\n");
	else printf("0\n"); 
	return 0;
}

F 抗议必胜2 (水题)

题目描述
2020年,抗击疫情,众志成城,我们一定能取得疫情战役最后的胜利(Victory)。乎乎想输出n行“China will win the battle against COVID-19.”,请帮他编程实现。

输入描述:
一行,一个整数n(3~100),表示输出的行数。

输出描述:
针对输入,输出n行“China will win the battle against COVID-19.”

输入

4

输出

China will win the battle against COVID-19.
China will win the battle against COVID-19.
China will win the battle against COVID-19.
China will win the battle against COVID-19.
signed main() {
 	int n = read();
 	for (int i = 0; i < n; ++i) {
 		printf("China will win the battle against COVID-19.\n");
	}
	return 0;
}

G 成绩统计 (水题)

题目描述

乎乎帮老师统计成绩,输入n个成绩,请编程统计输出n个成绩的平均分,最高分,最低分。

输入描述:

两行,第一行为n,表示n个成绩(3~10000)。

第二行为n个成绩(整数表示,范围0~100),以空格隔开。

输出描述:

一行,一个实数(小数点保留两位)和两个整数,用空格隔开,分别表示平均分,最高分,最低分。

输入

5
66 77 88 99 100

输出

86.00 100 66
signed main() {
 	int n = read();
 	int sum = 0;
 	int maxx = -1, minn = 101;
 	for (int i = 1; i <= n; ++i) {
 		int x = read();
 		sum += x;
 		maxx = max(maxx, x);
 		minn = min(minn, x);
	}
	printf("%.2lf %lld %lld", 1.0 * sum / n, maxx, minn);
	return 0;
}

H 抗议必胜3 (水题)

题目描述

2020年,抗击疫情,众志成城,我们一定能取得疫情战役最后的胜利(Victory)。乎乎想用大写字母V组成大V,请帮他编程实现。

输入描述:

一行,一个整数n(3~100), 表示大V的大小,也表示输出的行数。

输出描述:

针对输入的n,用大写字母V组成大V。

输入

4

输出

V     V
 V   V
  V V
   V

题目描述

乎乎得到了一组整数,他想知道其中每个整数出现的次数,请帮他编程实现。

输入描述:

输入两行,第一行,为一个整数n,范围为(3~1000),
第二行,输入n个整数,每个整数的范围为(1~10000),用空格隔开。

输出描述:

输出为n行,按整数大小从高到低输出其出现的次数,每行输出两个整数,为出现的整数和对应出现的次数,用“-”线隔开。

输入

7
3 2 3 4 3 2 1

输出

4-1
3-3
2-2
1-1

const int N = 10010;
int a[N];
signed main() {
 	int n = read();
 	int maxx = 0;
 	memset(a, 0, sizeof a);
 	for (int i = 1; i <= n; ++i) {
 		int x = read();
 		a[x]++;
 		maxx = max(maxx, x);
	}
	for (int i = maxx; i >= 1; --i) {
		if (a[i]) printf("%lld-%lld\n", i, a[i]);
	}
	return 0;
}

J 子序列求和(前缀和)

题目描述

乎乎得到一整数序列A1,A2,…,An,求A1-An中的一个子序列Ap-Aq的和,共T组测试。

输入描述:

输入为T+3行,
第一行,为一个整数n,范围为(3~1000),表示输入序列的长度,
第二行,输入n个整数,每个整数的范围为(1~1000),用空格隔开,
第三行,输入一个整数T,表示T组测试数据。
接下来T行,每行两个整数p和q(1 ≤ p≤ q≤10000),用空格隔开,第一个整数表示子序列的开始,第二个整数表示子序列的结束。

输出描述:

共T行,针对每组输入的子序列的开始和子序列的结束,输出子序列的和并换行,如果 n < p ≤ q,则输出0,如果 p ≤ n ≤ q,则输出p和q覆盖的子序列和。

输入

6
1 2 3 4 5 6
3
1 3
3 6
5 8

输出

6
18
11
const int N = 1010;
int a[N];
int sum[N];
signed main() {
	int n = read();
	for (int i = 1; i <= n; ++i) {
		a[i] = read();
		sum[i] = sum[i - 1] + a[i];
	}
	int t = read();
	while(t--) {
		int l = read(), r = read();
		if (l > n) {
			printf("0\n");
			continue;
		}
		if (r > n) r = n;
		printf("%lld\n", sum[r] - sum[l - 1]);
	}
	return 0;
}

K Simple Question (水题)

题目描述

对于给定的两个正整数 N , M N,M N,M,求闭区间 [ 1 , K ] [1,K] [1,K] 内能同时被 N 和 M 整除的最大值,如果答案不存在输出-1

输入描述:

输入三个正整数 N , M , K N,M,K N,M,K
1 ≤ N ≤ 1000 , 1 ≤ M ≤ 1000 , 1 ≤ K ≤ 1 0 9 1 ≤ N ≤ 1000 , 1 ≤ M ≤ 1000 , 1 ≤ K ≤ 109 1\leq N \leq1000, 1\leq M\leq 1000, 1\leq K \leq 10^{9}1≤N≤1000,1≤M≤1000,1≤K≤10 9 1N1000,1M1000,1K1091N1000,1M1000,1K109

输出描述:

输出一个正整数,即答案。如果答案不存在输出-1

输入

2 3 7

输出

6

示例2
输入

2 3 5

输出

-1

N Interesting Number (素数)

题目描述

我们定义 φ ( x ) φ(x) φ(x) x x x 的因子个数,那么 φ ( 1 ) = 1 , φ ( 9 ) = 3 φ(1)=1,φ(9)=3 φ(1)=1,φ(9)=3。如果 φ ( x ) = 3 φ(x)=3 φ(x)=3,那么我们就认为 x x x 是一个有趣的数,因此 9 9 9 是一个有趣的数。
给定一个闭区间[1, N],请你计算:在这个闭区间内有多少个有趣的数?

输入描述
输入一个正整数 N ( 1 ≤ N ≤ 1 0 12 ) (1≤N≤10^{12}) (1N1012)

输出描述
输出一个整数,即答案

输入
10
输出
2
说明
[1,10]内有两个有趣的数:4、9

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define int ll
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MOD 1e9 + 7
using namespace std;
int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
	return s * w;
}
//最大公约数
int gcd(int x,int y) {
    if(x<y) swap(x,y);//很多人会遗忘,大数在前小数在后
    //递归终止条件千万不要漏了,辗转相除法
    return x % y ? gcd(y, x % y) : y;
}
//计算x和y的最小公倍数
int lcm(int x,int y) {
    return x * y / gcd(x, y);//使用公式
}
int ksm(int a, int b, int mod) { int s = 1; while(b) {if(b&1) s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
//------------------------ 以上是我常用模板与刷题几乎无关 ------------------------//
bool prime(int m) {
    for (int i = 2; i <= sqrt(m); ++i) {
    	if (m % i == 0) return false;
	}
	return true; 
}
signed main(){
	int n = read();
	int ans = 0;
	double x;
	for (int i = 2; i <= n / i; ++i) {
		if (prime(i)) ans++;
	}
	printf("%lld\n", ans);
}

M Mutable Array (水题)

题目描述
现在你有一个包含N个正整数的数组Array,你只知道数组中的最小值是MIN,最大值是MAX,那么 ∑ i = 1 N A r r a y [ i ] \sum_{i = 1}^{N}{Array[i]} i=1NArray[i]
Array[i]有多少种不同的结果?
∑ i = 1 N A r r a y [ i ] \sum_{i = 1}^{N}{Array[i]} i=1NArray[i] = 数组元素的总和

输入描述
输入三个正整数 N , M I N , M A X N,MIN,MAX N,MIN,MAX
1 ≤ N ≤ 1 0 9 , 1 ≤ M I N ≤ M A X ≤ 1 0 9 1≤N≤10^9 ,1≤MIN≤MAX≤10^9 1N109,1MINMAX109

输出描述
输出一个正整数,即答案

示例1
输入

2 5 6

输出

1

示例2
输入

10000000 100 100

输出

1
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define int ll
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MOD 1e9 + 7
using namespace std;
int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
	return s * w;
}
//最大公约数
int gcd(int x,int y) {
    if(x<y) swap(x,y);//很多人会遗忘,大数在前小数在后
    //递归终止条件千万不要漏了,辗转相除法
    return x % y ? gcd(y, x % y) : y;
}
//计算x和y的最小公倍数
int lcm(int x,int y) {
    return x * y / gcd(x, y);//使用公式
}
int ksm(int a, int b, int mod) { int s = 1; while(b) {if(b&1) s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
//------------------------ 以上是我常用模板与刷题几乎无关 ------------------------//

signed main(){
	int n = read();
	int MIN = read(), MAX = read();
	if (n <= 2) printf("1\n");
	else {
		if (MAX == MIN) printf("1\n");
		else printf("%lld\n", (MAX - MIN) * (n - 2) + 1);
	}
	return 0;
}

N Find Difference(博弈论)

题目描述
现在你有 N 堆硬币,每堆硬币中都有 N 枚硬币。其中 N - 1 堆硬币中每枚硬币的重量都为 1g,只有剩下的一堆硬币中每枚硬币的重量为 2g,但你并不知道哪堆硬币中的硬币重量为 2g。
你有一个能称任意重量的电子秤,在最优策略下,请问最多需要称多少次就能知道哪堆硬币中的硬币重量为 2g?(可以把不同堆的硬币混合在一起称重,只需知道哪堆硬币中的硬币重 2g 即可)

输入描述:
输入一个正整数N
1 ≤ N ≤ 1 0 12 1≤N≤10^{12} 1N1012

输出描述:
输出一个整数,即答案

示例1
输入

2

输出

1

说明
从一堆硬币中拿出一枚硬币称重,如果重量为1g,那么另一堆硬币中硬币的重量都为2g;如果重量为2g,那么此堆硬币中的硬币重量都为2g

示例2
输入

1

输出

0
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define int ll
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MOD 1e9 + 7
using namespace std;
int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
	return s * w;
}
//最大公约数
int gcd(int x,int y) {
    if(x<y) swap(x,y);//很多人会遗忘,大数在前小数在后
    //递归终止条件千万不要漏了,辗转相除法
    return x % y ? gcd(y, x % y) : y;
}
//计算x和y的最小公倍数
int lcm(int x,int y) {
    return x * y / gcd(x, y);//使用公式
}
int ksm(int a, int b, int mod) { int s = 1; while(b) {if(b&1) s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
//------------------------ 以上是我常用模板与刷题几乎无关 ------------------------//

signed main(){
	int n = read();
	if (n == 1) printf("0\n");
	else printf("1\n");
	return 0;
}

P Dismantling Number (算一下时间复杂度,直接暴力好吧)

题目描述

给定一个正整数N,请你判断它能否表示成三个2的正整数(>0)次幂的和,如果能输出"YES",否则输出"NO"。(不包含引号)

输入描述:
输入一个正整数N
1 ≤ N ≤ 1 0 9 1≤N≤10^9 1N109

输出描述:

输出一行字符串"YES"或"NO"(不包含引号)

示例1

输入

10

输出

YES

说明
2 2 + 2 2 + 2 1 = 10 2^{2} + 2^{2} + 2^{1}=10 22+22+21=10

示例2

输入

4

输出

NO

示例3

输入

1024

输出

YES

说明
2 9 + 2 8 + 2 8 = 1024 2^{9}+2^{8}+2^{8}=1024 29+28+28=1024

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define int ll
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MOD 1e9 + 7
using namespace std;
int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
	return s * w;
}
//最大公约数
int gcd(int x,int y) {
    if(x<y) swap(x,y);//很多人会遗忘,大数在前小数在后
    //递归终止条件千万不要漏了,辗转相除法
    return x % y ? gcd(y, x % y) : y;
}
//计算x和y的最小公倍数
int lcm(int x,int y) {
    return x * y / gcd(x, y);//使用公式
}
int ksm(int a, int b, int mod) { int s = 1; while(b) {if(b&1) s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
//------------------------ 以上是我常用模板与刷题几乎无关 ------------------------//
const int N = 1010;
int a[N];
int sum[N];
signed main() {
	int n = read();
    for (int a = 2; a < n; a *= 2) {
        for (int b = 2; b < n; b *= 2) {
            for (int c = 2; c < n; c *= 2) {
                if (a + b + c == n) {
                    printf("YES\n");
                    return 0;
                }
            }
        }
    }
    printf("NO\n");
	return 0;
}

Q Finite Decimal(思维)

题目描述
小数部分的位数有限的小数被称为有限小数。例如0.123450.12345是有限小数, 1 3 \frac{1}{3} 31 、π是无限小数。
给你一个正整数n,请你判断 1 n \frac{1}{n} n1
是否为有限小数,如果是输出"YES",否则输出"NO"(不包含引号)

输入描述

第一行输入一个正整数TT,代表测试用例的组数
接下来TT行,每行输入一个正整数nn
1 ≤ T ≤ 1000 , 1 ≤ n ≤ 10000 1\leq T\leq 1000,1\leq n\leq 10000 1T1000,1n10000

输出描述

对于每组输入,输出一行字符串"YES"或"NO"(不包含引号)

示例1
输入

3
1
3
5

输出

YES
NO
YES

说明
1 1 = 1 , 1 3 = 0.33333 ⋅ ⋅ ⋅ ⋅ , 1 5 = 0.2 \frac{1}{1}=1,\frac{1}{3}=0.33333····,\frac{1}{5}=0.2 11=1,31=0.3333351=0.2

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define int ll
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MOD 1e9 + 7
using namespace std;
int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
	return s * w;
}
//最大公约数
int gcd(int x,int y) {
    if(x<y) swap(x,y);//很多人会遗忘,大数在前小数在后
    //递归终止条件千万不要漏了,辗转相除法
    return x % y ? gcd(y, x % y) : y;
}
//计算x和y的最小公倍数
int lcm(int x,int y) {
    return x * y / gcd(x, y);//使用公式
}
int ksm(int a, int b, int mod) { int s = 1; while(b) {if(b&1) s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
//------------------------ 以上是我常用模板与刷题几乎无关 ------------------------//
const int N = 1010;
int check(int n) {
	if (n == 1) return 1;
	else if (n % 2 == 0) return check(n / 2);
	else if (n % 5 == 0) return check(n / 5);
	else return 0;
}
int a[N];
int sum[N];
signed main() {
	int t = read();
	while (t--) {
		int n = read();
		if (check(n)) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

R Take Apples (博弈论)

题目描述
小A和小B共有N个苹果,他们准备玩一个游戏,获胜的人将赢得所有苹果。
游戏规则如下:两人轮流取苹果,每一轮两人各取一次苹果(至少取一个),第一轮每人最多取1个苹果、第二轮每人最多取2个苹果、······、第k轮每人最多取k个苹果。
游戏会一直进行下去,直到所有苹果被取完,取完最后一个苹果的人获胜。
小A比较谦让,所以让小B先手取苹果。现在小A想问你:在最优策略下,他能否获胜呢?如果能请回答"YES",否则回答"NO"(不包含引号)

输入描述
第一行输入一个正整数TT,代表测试用例的组数
接下来TT行,每行输入一个正整数N
1 ≤ T ≤ 1000 , 1 ≤ N ≤ 1 0 9 1≤T≤1000,1≤N≤10^9 1T1000,1N109

输出描述
对于每组输入,输出一行字符串"YES"或"NO"(不包含引号)
示例1
输入

3
1
2
7

输出

NO
YES
NO

说明
N=1时,小B取1个苹果,小B胜
N=2时,小B取1个苹果,小A取1个苹果,小A胜
N=7时,小B取1个苹果,小A取1个苹果,小B选择再取1个苹果,还剩下4个苹果,此时小A只能取1或2个苹果,但下一轮小B取苹果个数的范围是[1,3],总能取完苹果

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define int ll
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MOD 1e9 + 7
using namespace std;
int read()
{
	int w = 1, s = 0;
	char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
	return s * w;
}
//最大公约数
int gcd(int x,int y) {
    if(x<y) swap(x,y);//很多人会遗忘,大数在前小数在后
    //递归终止条件千万不要漏了,辗转相除法
    return x % y ? gcd(y, x % y) : y;
}
//计算x和y的最小公倍数
int lcm(int x,int y) {
    return x * y / gcd(x, y);//使用公式
}
int ksm(int a, int b, int mod) { int s = 1; while(b) {if(b&1) s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
//------------------------ 以上是我常用模板与刷题几乎无关 ------------------------//

signed main(){
	int t = read();
	while (t--) {
		int n = read();
		int k = 1;
		while (n > k + 1) {
			n -= k + 1;
			k ++;
		}
		if (n >= 1 && n <= k) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值