第一题 三角形的分类
题目描述
给定三个角度 a a a, b b b 及 c c c。请判断这三个角在平面上能组成什么样的三角形:
如果不能组成三角形,输出 E r r o r Error Error
如果能组成等边三角形,输出 E q u i l a t e r a l Equilateral Equilateral
如果能组成等腰直角三角形,输出 I s o s c e l e s r i g h t Isosceles right Isoscelesright
如果能组成等腰三角形,输出 I s o s c e l e s Isosceles Isosceles
如果能组成直角三角形,输出 R i g h t Right Right
如果能组成不等边三角形,输出 S c a l e n e Scalene Scalene
输入格式
第一行:第一个角的角度 a a a
第二行:第二个角的角度 b b b
第三行:第三个角的角度 c c c
输出格式
根据题目要求输出对应的文字
数据范围
1 ≤ a , b , c ≤ 180 1\leq a,b,c\leq 180 1≤a,b,c≤180
样例数据
输入:
60
60
60
输出:
Equilateral
分析:if语句嵌套就行了
代码: 100分
#include <bits/stdc++.h>
using namespace std;
int main(){
//freopen("","r",stdin);
//freopen("","w",stdout);
long long a,b,c;
cin>>a>>b>>c;
if(a==180||b==180||c==180||a+b>=180||a+c>=180||b+c>=180||a+b+c>180){
cout<< "Error" << endl;
return 0;
}
if(a==b&&b==c&&a==c){
cout<< "Equilateral" << endl;
}else if(a==90&&b==c||b==90&&a==c||c==90&&a==b){
cout<< "Isosceles right" << endl;
}else if(a==c||a==b||b==c){
cout<< "Isosceles" << endl;
}else if(a==90||b==90||c==90){
cout<< "Right" << endl;
}else{
cout<< "Scalene" << endl;
}
//fclose(stdin);
//fclose(stdout);
return 0;
}
第二题 区间最大公约数
题目描述
给定两个正整数 L , R L,R L,R,你可以任意选择两个正整数 x , y x,y x,y且满足 L ≤ x < y ≤ R L \leq x \lt y \leq R L≤x<y≤R,并求出 x , y x,y x,y的最大公约数。
请问在所有选法中, x , y x,y x,y最大公约数的最大值为多少?
输入格式
输入共一行,两个正整数表示 L , R L,R L,R
输出格式
输出共一个整数,表示所求答案
数据范围
对于 30 % 30\% 30%的数据, 1 ≤ L < R ≤ 100 1\leq L \lt R \leq 100 1≤L<R≤100
对于 60 % 60\% 60%的数据, 1 ≤ L < R ≤ 1 0 3 1\leq L \lt R \leq 10^3 1≤L<R≤103
对于 100 % 100\% 100%的数据, 1 ≤ L < R ≤ 5 × 1 0 5 1\leq L \lt R \leq 5\times10^5 1≤L<R≤5×105
样例数据
输入:
23 29
输出:
4
说明:
选(24,28)时,取到最大值为 4
输入:
32678 65536
输出:
32768
输入:
32768 32769
输出:
1
分析1:直接暴力!!!
代码:60分
#include <bits/stdc++.h>
using namespace std;
long long l,r,ans=0;
long long gcd(long long x,long long y){//最大公约数递归,不会函数的用辗转相除法,不要用枚举公约数,那效率感人
if(y==0){
return x;
}else{
return gcd(y,x%y);
}
}
int main(){
//freopen("","r",stdin);
//freopen("","w",stdout);
cin>>l>>r;
for(int i=l;i<r;++i){//暴力硬推
for(int j=i+1;j<=r;++j){
long long cnt=gcd(i,j);
ans=max(ans,cnt);
}
}
cout<< ans << endl;
//fclose(stdin);
//fclose(stdout);
return 0;
}
分析2:改变一下思路
由于暴力只能拿到60分,想更高只能采取偷袭的方法
改变一下策略,之前是枚举两个数,再求公因数,那我枚举公因数,看适合它的较大那数是否超过 R R R就行了
代码2 :100分
#include <bits/stdc++.h>
using namespace std;
long long x,y,ans=1;//定义1是因为找不到公因数的话那最大就是1
int main(){
cin>>x>>y;
for(int i=2;i<=y;++i) if(((x+i-1)/i+1)*i<=y) ans=i;//判断
cout<< ans << endl;
return 0;
}
第三题 滑雪训练
题目描述
小爱最近迷上了滑雪,某滑雪场有 n n n 条不同难度的雪道,只有学习并滑了第 i i i 条雪道,才能去参加第 i + 1 i+1 i+1 条雪道的学习与训练。
已知,第一次滑第 i i i 条雪道时,需要先进行 a i a_i ai分钟的学习,再花 b i b_i bi 分钟滑该雪道一次,才算学习完成。若之后再滑第 i i i 条雪道,则仅需 b i b_i bi 分钟即可滑一次。
小爱共有 T T T 分钟时间,请问如何安排才能使他能滑的圈数最多?
输入格式
输入第一行,两个正整数 n , T n,T n,T
接下来 n n n 行:每行两个正整数 a i , b i a_i,b_i ai,bi 表示第 i i i条雪道需要的学习时间和滑雪时间。
输出格式
输出一个正整数,表示小爱最多可以滑的圈数。
数据范围
对于 30 % 30\% 30%的数据, 1 ≤ n ≤ 10 1\leq n \leq 10 1≤n≤10
对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 1 0 3 1\leq n \leq 10^3 1≤n≤103
对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 1 0 5 1\leq n \leq 10^5 1≤n≤105, 1 ≤ a i , b i , T ≤ 1 0 18 1 \leq a_i,b_i,T \leq 10^{18} 1≤ai,bi,T≤1018
样例数据
输入:
3 100
10 20
5 5
20 10
输出:
14
说明:
先花30分钟学习第一滑道,此时共计滑了一圈
在花10分钟学习第二滑道,此时共计滑了两圈
剩余60分钟,滑第二滑道,共计滑了14圈
分析 1:直接暴推!!
代码1:30分
略
分析2:前缀和来帮忙
在代码中,有一种算法可以 O ( 1 ) O(1) O(1)求区间和,他就是前缀和!
利用前缀和算出到第 i i i圈时要花多少时间,然后看当前圈减掉学习时间后还能滑多少圈,在打擂台求出最大,就行了
代码2:100分
#include <bits/stdc++.h>
using namespace std;
long long n,s[100010],b[100010],t,x,ans=0;
int main(){
cin>>n>>t;
for(int i=1;i<=n;++i) cin>>x>>b[i],s[i]=s[i-1]+x+b[i];//前缀和
for(int i=1;i<=n;++i) if(t>=s[i]) ans=max(ans,i+(t-s[i])/b[i]);//打擂台
cout << ans << endl;
return 0;
}
第四题 混乱的文本
题目描述
小爱正在使用一种文本编辑器输入文字。文本编辑器的工作机制如下:
若用户键入一个 [ [ [,则光标立即跳到文本的开头;
若用户键入一个 ] ] ],则光标立即跳到文本的末尾;
若用户键入任意字母,则在光标处插入该字母,且光标停留在新插入字母的后面。
给定一个字符序列,表示小爱敲击键盘录入的符号序列,请输出最后获得的文本。
输入格式
一个字符序列:表示键入的字符序列。
输出格式
一个字符序列:表示最后获得的文本。
数据范围
设 n n n 表示输入字符序列的长度
30 % 30\% 30% 的数据, 1 ≤ n ≤ 1000 1\leq n \leq 1000 1≤n≤1000
60 % 60\% 60% 的数据, 1 ≤ n ≤ 20 , 000 1\leq n \leq 20,000 1≤n≤20,000
100 % 100\% 100% 的数据, 1 ≤ n ≤ 300 , 000 1\leq n \leq 300,000 1≤n≤300,000
样例数据
输入:
abc[xyz]efg
输出:
xyzabcefg
分析:先看一组样例:
xyz[hd[hk[df]hgl
那如果我把’['中的字串全取出来:
hd
hk
df
再倒序输出一下:
dfhkhd
再加上’['外的:
dfhkhdxyzhgl
和结果相比:
dfhkhdxyzhgl
dfhkhdxyzhgl
这不一毛一样!!!
代码:100分
#include <bits/stdc++.h>
using namespace std;
string s,s1[300010],s2;
long long ans=0;
char op=']';
int main() {
cin>>s;
for(int i=0;i<s.size();++i){
if(s[i]=='['){
op='[';
ans++;
}else if(s[i]==']'){
op=']';
}else{
if(op=='['){
s1[ans]+=s[i];
}
if(op==']'){
s2+=s[i];
}
}
}
for(int i=ans;i>=1;--i){
cout<< s1[i];
}
cout<< s2 << endl;
return 0;
}
第五题最大子阵和
题目描述
给定 n × n n×n n×n 个整数组成一个方阵 a i , j a_i,_j ai,j ,请找一个 k × k k×k k×k 的子方阵,使得子方阵内的数字之和达到最大,输出这个最大值。
输入格式
第一行:两个整数 n n n 与 k k k
第二行到第 n + 1 n+1 n+1 行:每行 n n n 个整数表示 a i , j a_i,_j ai,j
输出格式
单个整数:表示最大的 k × k k×k k×k 的子方阵的数字之和。
数据范围
30 % 30\% 30% 的数据, 1 ≤ k ≤ n ≤ 30 1≤k≤n≤30 1≤k≤n≤30
60 % 60\% 60% 的数据, 1 ≤ k ≤ n ≤ 300 1≤k≤n≤300 1≤k≤n≤300
100 % 100\% 100% 的数据, 1 ≤ k ≤ n ≤ 2500 , 0 ≤ a i , j ≤ 1 , 000 , 000 1≤k≤n≤2500,0≤a_i,_j ≤1,000,000 1≤k≤n≤2500,0≤ai,j≤1,000,000
样例数据
输入:
3 2
1 2 3
3 1 2
0 2 4
输出:
9
说明:
右下角最大
分析1:直接暴推!!!
代码1:30分
#include <bits/stdc++.h>
using namespace std;
long long n,k,a[3010][3010],ans=0;
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n-k+1;i++){
for(int j=1;j<=n-k+1;++j){
long long cnt=0;
for(int x=i;x<=i+k-1;++x){
for(int y=j;y<=j+k-1;++y){
cnt+=a[x][y];
}
}
ans=max(ans,cnt);
}
}
cout << ans << endl;
return 0;
}
分析2:二维前缀和
先看一章图:
a[x][y]的面积怎么求??
答: a x , y − 1 a_x,_y-1 ax,y−1+ a x + 1 , y a_x+1,_y ax+1,y- a x − 1 , y − 1 a_x-1,_y-1 ax−1,y−1+m
那事先处理好数组,再把这个公式稍微改一下:
a x , y − a x − k , y − a x , y − k + a x − k , y − k a_x,_y-a_x-k,_y-a_x,_y-k+a_x-k,_y-k ax,y−ax−k,y−ax,y−k+ax−k,y−k
不过要注意,当极限数据时读入会超时,可以换scanf和printf或者关同步,或快读(本来想写快读的,没想到当天一交,就对了,那就鸽了吧)
代码2:100分
#include <bits/stdc++.h>
using namespace std;
long long s[2510][2510],n,ans=0,k,t,cnt=0;
int main(){
//freopen("","r",stdin);
//freopen("","w",stdout);
ios::sync_with_stdio(false);\\关同步,注意关同步后,只能用cin,cout或scanf,printf,不然会出错
scanf("%lld %lld",&n,&k);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
scanf("%lld",&t);
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+t;
}
}
for(int i=k;i<=n;++i){
for(int j=k;j<=n;++j){
ans=max(ans,s[i][j]-s[i-k][j]-s[i][j-k]+s[i-k][j-k]);
}
}
printf("%lld\n",ans);
//fclose(stdin);
//fclose(stdout);
return 0;
}