上海市计算机学会2022年10月月赛丙组

T1-直角三角形的判定

题目描述

给定三个正整数表示三角形的三条边,请判定它是否为直角三角形。

输入格式

第一行:三个整数 a a a b b b c c c

输出格式

若可以构成一个直角三角形,输出 R i g h t Right Right T r i a n g l e Triangle Triangle

否则,输出 N o No No

数据范围

1 ≤ a , b , c ≤ 1000 1 \le a, b, c \le 1000 1a,b,c1000

样例输入1

3 4 5

样例输出1

Right Triangle

样例输入2

3 3 3

样例输出2

No

分析

只需要用分支结构将三个数的最大值交换到c中,再用勾股定理判断就可以了

代码如下

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

int main(){
	int a, b, c;
	cin >> a >> b >> c;
	if (a > b) swap(a, b);
	if (a > c) swap(a, c);
	if (b > c) swap(b, c);
	if (a * a + b * b == c * c)
		cout << "Right Triangle" << endl;
	else
		cout << "No" << endl;
	return 0;
}

T2-因子分解

题目描述

给定一个正整数 n n n,请将它分解为素数的乘积。

例如 60 = 2 × 2 × 3 × 5 60 = 2 \times 2 \times 3 \times 5 60=2×2×3×5

输入格式

单个整数表示 n n n

输出格式

若干整数表示 n n n 的素因子,按照从小到大的顺序输出。

数据范围

2 ≤ n ≤ 1 , 000 , 000 , 000 2 \leq n \leq 1,000,000,000 2n1,000,000,000

样例输入1

60

样例输出1

2 2 3 5

样例输入2

3

样例输出2

3

分析

  • 枚举n的因子,然后用n除以这个因子,直到无法整除,这样找到的因子一定是素因子
for (int i = 2; i <= n; ++i)
	while (n % i == 0){
		cout << i << " ";
		n /= i;
	}

时间复杂为O(n),超时了

  • 结论:整数n大于 n \sqrt n n 的因子只可能有0个或1个
    所以,只要枚举到 n \sqrt n n 即可,如果最后n没有变成1,则n一定是唯一的大于 n \sqrt n n 的素因子。时间复杂度为O( n \sqrt n n )。
#include <bits/stdc++.h>
using namespace std;

int main(){
   int n, m;
   cin >> n;
   m = n;
   for (int i = 2; i * i <= n; ++i){
   	while (m % i == 0){
   		cout << i << " ";
   		m /= i;
   	}
   }
   if (m != 1) cout << m << endl;
   return 0;
}

T3-算式求值(一)

题目描述

给定一个由正整数、加号、减号构成的表达式,请计算表达式的值。

输入格式

输入一个由 正整数、 + + + − - 构成的表达式

输出格式

单个整数:表示算式的值。

数据范围

数据保证

  • 输入的字符串长度不超过 100,000,
  • 其中出现的整数不超过 10000。

样例输入

2+12-5

样例输出

9

分析

读入字符串,将数字拆出来,再根据数字前的符号进行运算就可以了。

#include <bits/stdc++.h>
using namespace std;
string st;

int cnt (int f, int e){
	int n = 0;
	for (int i = f; i <= e; ++i)
		n = n * 10 + st[i] -'0';
	if (st[f - 1] == '-')
		n = -n;
	return n;
}

int main(){
	cin >> st;
	st += '+';
	int len = st.size();
	int f = 0, e, ans = 0, s = 0;
	for (int i = 0; i < len; ++i){
		if ((st[i] != '+' || st[i] != '-') && (st[i - 1] == '+' || st[i - 1] == '-'))
			f = i;
		if ((st[i] != '+' || st[i] != '-') && (st[i + 1] == '+' || st[i + 1] == '-')){
			e = i;
			s = cnt(f, e);
			ans += s;
		}
	}
	cout << ans << endl;
    return 0;
}

T4-门禁记录

题目描述

小爱得到了某大楼一天内按时间顺序记录的 n n n条门禁出入记录,每条记录由两个字符串组成,第一个字符串为出入人员姓名,第二个字符串表示该人员进出状态、为 enter 或 exit 中一项,其中 enter 为进入, exit 为离开。

小爱发现,部分人员的门禁信息存在错误,即某人在没有进入记录时便有了离开记录,或是某人有进入记录但没有离开记录。

已知在第一条记录前及最后一条记录后,大楼内均没有任何人员。请你根据门禁记录,来分析哪些人员的门禁信息存在错误?

输入格式

输入第一行,一个正整数 n n n
接下来 n n n 行,每行两个字符串,以空格隔开,其中第 i + 1 i+1 i+1行的两字符串分别表示第 i i i条记录的人员姓名与出入信息。

输出格式

按字典序输出所有出入信息存在错误的人员姓名,按空格隔开

数据范围

  • 对于 30 % 30\% 30%的数据, 1 ≤ n ≤ 10 1 \leq n \leq 10 1n10
  • 对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 10 1 \leq n \leq 10 1n10
  • 对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 2 × 1 0 4 1 \leq n \leq 2 \times 10^4 1n2×104,且人员姓名字符串长度不超过10。

样例输入

5
Xiaoai enter
Bob exit
Xiaoai exit
Alice exit
Alice enter

样例输出

Alice Bob

说明

Bob只有exit数据,存在信息缺失
Alice的exit数据前不存在enter,而在最后一条enter后也没有exit,存在信息缺失

分析

模拟,用t来记录状态,用vh来判断状态是否出现错误,然后将答案存入ans数组中并排序,最后去重。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e4 + 10;
string s, t, a[maxn], ans[maxn];
int n, vh[maxn], m = 0, js = 0;

int main(){
	cin >> n;
	for (int i = 0; i < n; ++i){
		cin >> s >> t;
		int pos = -1;
		for (int j = 0; j < m; ++j)
			if (a[j] == s) pos = j;
		if (pos == -1){
			pos = m;
			a[m++] = s;
		}
		if (t == "enter"){
			if (vh[pos] == 1)
				ans[js++] = s;
			else
				vh[pos] = 1;
		}
		if (t == "exit"){
			if (vh[pos] == 0)
				ans[js++] = s;
			else
				vh[pos] = 0;
		}
	}
	for (int i = 0; i < m; ++i)
		if (vh[i]) ans[js++] = a[i];
	sort(ans, ans + js);
	cout << ans[0];
	for (int i = 1; i < js; ++i)
		if (ans[i] != ans[i - 1])
			cout << " " << ans[i];
	cout << endl;
	return 0;
}

T5-组队竞赛

题目描述

n n n同学想要参加小爱组建的一支信息学竞赛队伍,每位同学有能力值 a i a_i ai与热情度 b i b_i bi

小爱认为,如果队伍当中,能力值最大与能力值最小选手之间,能力差值大于给定 X X X,会导致能力差距过大、不利于团队的学习与凝聚力。因此,请你帮助小爱计算下,如何选择队伍的选手,才能使所有选手的能力差值小于等于 X X X,且热情度最大。

输入格式

输入第一行,一个正整数 n n n,表示有 n n n位选手
接下来 n n n行,每行两个正整数 a i a_i ai, b i b_i bi
表示每位选手的能力值与热情度。
最后一行,一个正整数 X X X,表示小爱希望的能力差值上限

输出格式

输出一个整数,表示满足条件的情况下,最大热情度的值

数据范围

  • 对于 30 % 30\% 30%的数据, 1 ≤ n ≤ 100 1 \leq n \leq 100 1n100
  • 对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 1 0 4 1 \leq n \leq 10^4 1n104
  • 对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 1 0 5 , 1 ≤ d ≤ 1 0 9 , 1 ≤ a i , b i ≤ 1 0 9 1 \leq n \leq 10^5,1 \leq d \leq 10^9,1 \leq a_i,b_i \leq 10^9 1n105,1d109,1ai,bi109

样例输入

5
10 21
20 34
30 27
40 89
50 54
20

样例输出

170

说明

选第3、4、5个选手。
能力值分别为30、40、50,不超过50-30=20给定的能力差值上限20
此时热情度为27+89+54=170

分析

求能力值相差不超过x,最大热情值的和。

将能力值排序,于是问题就变成了差值不大于 X X X的最大热情度区间和。 l l l为1, r r r向后移动找到差值不大于 X X X的最远的人,维护热情度的值,求出左端点为1的最大区间和。 l l l每次向后移动, r r r不断向后找出差值不大于 X X X的最远的人。当 r r r = n n n时,就可以得出解。时间复杂度为 O O O( n n n l o g log log n n n)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;

struct nod{
	int nl, rq;
} a[maxn];

bool cmp(nod p, nod q){
	return p.nl < q.nl;
}

int n, x;

int main(){
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> a[i].nl >> a[i].rq;
	cin >> x;
	sort(a, a + n, cmp);
	long long ans = 0, s = 0int l = 0, r = 0;
	while (r < n){
		while (r < n && a[r].nl - a[l].nl <= x){
			s += a[r].rq;
			r++;
		}
		ans = max(ans, s);
		s -= a[l].rq;
		l++;
	}
	cout << ans << endl;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值