年终比赛地址
今天写一下自己对最近比赛的一次总结,以及对2019的总结。
首先先写一下最近比赛的总结。
问题 A: 字符串的输入输出处理
题目描述
字符串的输入输出处理。
输入
第一行是一个正整数N,最大为100。之后是多行字符串(行数大于N), 每一行字符串可能含有空格,字符数不超过1000。
输出
先将输入中的前N行字符串(可能含有空格)原样输出,再将余下的字符串(不含有空格)以空格或回车分割依次按行输出。每行输出之间输出一个空行。
样例输入
2
www.dotcpp.com DOTCPP
A C M
D O T CPP
样例输出
www.dotcpp.com DOTCPP
A C M
D
O
T
CPP
思路:第一道题还是挺简单的,考查输入输出,gets(),puts(),sacnf("%s",a)printf("%s",a)的一些区别,首先我们要知道,输入字符串的时候他们都是怎么读取结束的,前n行需要原样输出(可能包含空格),所以我们使用gets()函数以换行结束,能读取空格,后面由于不清数输入多少行字符,默认以文件(EOF)结尾,该处遇到空格或换行就输出,因此使用%s输入输出
code:
# include<stdio.h>
int main()
{
int N,i;
scanf("%d",&N);
char a[1000];
getchar();
for(i=0;i<N;i++)//输入n行
{
gets(a);
puts(a);
printf("\n");
}
while(scanf("%s",a)!=EOF)//默认以文件结尾
{
printf("%s\n",a);
printf("\n");
}
return 0;
}
问题 B: [信息学奥赛一本通-T1005]地球人口承载力估计
题目描述
假设地球上的新生资源按恒定速度增长。照此测算,地球上现有资源加上新生资源可供x亿人生活a年,或供y亿人生活b年。
为了能够实现可持续发展,避免资源枯竭,地球最多能够养活多少亿人?
输入
输入只有一行,包括四个正整数x,a,y,b,两个整数之间用单个空格隔开。x>y,a<b,ax<by,各整数均不大于10000。
输出
一个实数z,表示地球最多养活z亿人,舍入到小数点后两位。
样例输入
110 90 90 210
样例输出
75.00
思路:来源于信息学奥赛题,一开始毫无头绪,还是搜了题解,才明白是个怎么回事,可能自己的逻辑不清楚吧,就当自己扩展知识吧
设每1亿人,每年消耗资源1份,110亿人90年消耗资源11090=9900份,90亿人210年消耗资源90210=18900份,每年新生资源(18900-9900)/(210-90)=75份,不必深究此题
code:
# include<stdio.h>
int main()
{
double x,a,y,b,ans;
scanf("%lf%lf%lf%lf",&x,&a,&y,&b);
ans=(b*y-x*a)/(b-a);
printf("%0.2lf",ans);
return 0;
}
问题 C: [信息学奥赛一本通-T1242]网线主管
题目描述
仙境的居民们决定举办一场程序设计区域赛。裁判委员会完全由自愿组成,他们承诺要组织一次史上最公正的比赛。他们决定将选手的电脑用星形拓扑结构连接在一起,即将它们全部连到一个单一的中心服务器。为了组织这个完全公正的比赛,裁判委员会主席提出要将所有选手的电脑等距离地围绕在服务器周围放置。
为购买网线,裁判委员会联系了当地的一个网络解决方案提供商,要求能够提供一定数量的等长网线。裁判委员会希望网线越长越好,这样选手们之间的距离可以尽可能远一些。该公司的网线主管承接了这个任务。他知道库存中每条网线的长度(精确到厘米),并且只要告诉他所需的网线长度(精确到厘米),他都能够完成对网线的切割工作。但是,这次,所需的网线长度并不知道,这让网线主管不知所措。你需要编写一个程序,帮助网线主管确定一个最长的网线长度,并且按此长度对库存中的网线进行切割,能够得到指定数量的网线。
输入
第一行包含两个整数N和K,以单个空格隔开。N(1 ≤ N ≤ 10000)是库存中的网线数,K(1 ≤ K ≤ 10000)是需要的网线数量。接下来N行,每行一个数,为库存中每条网线的长度(单位:米)。所有网线的长度至少1m,至多100km。输入中的所有长度都精确到厘米,即保留到小数点后两位。
输出
网线主管能够从库存的网线中切出指定数量的网线的最长长度(单位:米)。必须精确到厘米,即保留到小数点后两位。
若无法得到长度至少为1cm的指定数量的网线,则必须输出“0.00”(不包含引号)。
样例输入
4 11
8.02
7.43
4.57
5.39
样例输出
2.00
思路:使用二分法,先找出最大一条网线当右端,0为左端,求mid=(L+R)/2,循环n个长度,求出ans与k比较>=k说明mid应该往本身的右边走,使L=min,往右走,ans<k,说明mid需要往左走,才能满足ans接近于k,最后就能找到最长的网线
code:
# include<iostream>
# include<algorithm>
using namespace std;
int a[10001],Max=0,ans=0;
int main()
{
int n,k;
cin>>n>>k;
double x;
for(int i=0;i<n;i++)
{
cin>>x;
a[i]=x*100;
Max=max(Max,a[i]);
}
//cout<<Max;
int l=0,r=Max+1,Min;
while(l<r)
{
ans=0;
Min=(r+l+1)/2;
for(int i=0;i<n;i++)
{
ans+=a[i]/Min;
}
if(ans>=k)
l=Min;
else
r=Min-1;
printf("%d %d\n",l,r);
}
printf("%0.2lf\n",l/100.00);
return 0;
}
问题 D: [蓝桥杯][2018年第九届真题]递增三元组
题目描述
给定三个整数数组
A = [A1, A2, … AN],
B = [B1, B2, … BN],
C = [C1, C2, … CN],
请你统计有多少个三元组(i, j, k) 满足:
- 1 <= i, j, k <= N
- Ai < Bj < Ck
- 输入
第一行包含一个整数N。 第二行包含N个整数A1, A2, … AN。 第三行包含N个整数B1, B2, … BN。 第四行包含N个整数C1, C2, … CN。
输出
一个整数表示答案
样例输入
3
1 1 1
2 2 2
3 3 3
样例输出
27
提示
对于30%的数据,1 <= N <= 100 对于60%的数据,1 <= N <= 1000 对于100%的数据,1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000
思路:一开始感觉挺简单的直接三个个for循环直接判断不就OK了?那你就大错特错了,你只能拿9分,因为见到的题目少,所以贴上大佬的思路吧,首先其实就是一个 三个数组符合a[i]<b[j]<c[k]就行菜鸟行为就是直接三个数组每次直接比较符合+1,也能出来样例的答案,但是你要注意测试数据 太大了,直接超限 进阶思路:新增一个数组存t[]中 存放比b[j]小的a[j]之前有多少个数(首先你得先排序)然后去c数组中找比b[]大的元素的个数,每次都移动b数组,找到就求sum结果就是sum时间复杂度大大降低
code:
# include<iostream>
# include<string.h>
# include<algorithm>
using namespace std;
int a[100001],b[100001],c[100001],t[100001],n;
long long sum=0;
int main()
{
int i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
for(i=0;i<n;i++)
{
scanf("%d",&c[i]);
}
sort(a,a+n);
sort(b,b+n);
sort(c,c+n);
memset(t,0,sizeof(t));
i=n-1,j=n-1;
while(i>=0&&j>=0)
{
if(b[j]>a[i])
{
t[j]=i+1;
j--;
}
else
i--;
}
i=0,j=0;
while(i<n&&j<n)
{
if(b[i]<c[j])
{
sum+=t[i]*(n-j);
i++;
}
else
j++;
}
printf("%lld\n",sum);
return 0;
}
问题 F: [蓝桥杯][算法提高VIP]上帝造题五分钟
题目描述
第一分钟,上帝说:要有题。于是就有了L,Y,M,C
第二分钟,LYC说:要有向量。于是就有了长度为n写满随机整数的向量
第三分钟,YUHCH说:要有查询。于是就有了Q个查询,查询向量的一段区间内元素的最小值
第四分钟,MZC说:要有限。于是就有了数据范围
第五分钟,CS说:要有做题的。说完众神一哄而散,留你来收拾此题
输入
第一行两个正整数n和Q,表示向量长度和查询个数
接下来一行n个整数,依次对应向量中元素:a[0],a[1],…,a[n-1]
接下来Q行,每行两个正整数lo,hi,表示查询区间[lo, hi]中的最小值,即min(a[lo],a[lo+1],…,a[hi])。
输出
共Q行,依次对应每个查询的结果,即向量在对应查询区间中的最小值。
样例输入
7 4
1 -1 -4 8 1 2 -7
0 0
1 3
4 5
0 6
样例输出
1
-4
1
-7
提示
第一个查询[0,0]表示求min{a[0]}=min{1}=1
第二个查询[1,3]表示求min{a[1],a[2],a[3]}=min{-1,-4,8}=-4
第三个查询[4,5]表示求min{a[4],a[5]}=min{1,2}=1
第四个查询[0,6]表示查询整个向量,求min{a[0…6]}=min{1,-1,-4,8,1,2,-7}=-7
思路:看到这道题的时候,终于让我看到了以往,来了一道简单题,就是给你两个数值让你在这个区间查找最小值返回就行了,注意一下是从下标0开始的就行了
code:
# include<iostream>
# include<algorithm>
using namespace std;
int a[10000];
int fun(int l,int r)
{
int min=999999;
for(int i=l;i<=r;i++)
{
if(a[i]<=min)
{
min=a[i];
}
}
return min;
}
int main()
{
int n,q;
int l,r;
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<q;i++)
{
cin>>l>>r;
printf("%d\n",fun(l,r));
}
return 0;
}
2019年的总结
今年成长的还算可以,从一开始c语言学的基础还行,尤其是指针方面掌握的可以,后来在因仑班了解了蓝桥杯,ACM大赛含金量很高,不是考个二级证书就能比的了得,好在基本功扎实,拿到了去蓝桥杯的名额,这两个月疯狂刷算法题,c语言网,计蒜客都有,截止现在对一些题目对有了一定的了解吧。怎么说呢,我现在终于有了一些目标,不局限于平常的考试过就万事大吉了,我想对专业知识更加的了解吧,目前只想把数据结构,c++学的更精,最后一天,希望明年的自己更加努力,不说了,睡觉咯。
*备战蓝桥*-~-!
2019.12.31