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 1≤a,b,c≤1000
样例输入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 2≤n≤1,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 1≤n≤10
- 对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 10 1 \leq n \leq 10 1≤n≤10
- 对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 2 × 1 0 4 1 \leq n \leq 2 \times 10^4 1≤n≤2×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 1≤n≤100
- 对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 1 0 4 1 \leq n \leq 10^4 1≤n≤104
- 对于 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 1≤n≤105,1≤d≤109,1≤ai,bi≤109
样例输入
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 = 0;
int 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;
}