计蒜客 光合作用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计蒜客 光合作用相关的知识,希望对你有一定的参考价值。
du熊是个爱学习的孩子,他总喜欢在生活中做一些小实验,这次du熊想研究一下光合作用。
du熊的实验材料有如下几样:神奇的种子,普通的纸箱和一些光源。一开始du熊将种子均匀的种在了箱子底部,你可以将其看成X轴,种子的位置为X轴上的点。然后du熊用纸板将箱子盖住,并在纸板上安装了一些光源(具体见图)。神奇的种子会在有光的情况下一直向上生长直到没光为止。现在du熊想知道当实验结束时每颗种子的高度是多少?
顶上的为光源,光源两边与顶部的夹角都为45°,黄色部分为光照,绿色的为植物。
输入第一行给出一个T,表示测试数据的组数。每组数据的第一行是三个整数n,m,H(1≤n≤100,000, 0≤m≤100,000, 1≤H≤10,000),n表示种子数(编号1-n),m表示光源数,H表示箱子的高度。接下来m行,每行一个整数Xi表示第i个光源在顶部的位置。????
对于每组测试数据,请输出n行,每行一个数表示第i颗种子的最终高度。
样例1
输入:
2
7 1 2
4
4 4 1
1
2
3
4
输出:
0
0
1
2
1
0
0
1
1
1
1
- #include <stdio.h>
- #include <string.h>
- #define abs(a) ((a)>0?(a):(-a))
- #define M 100000
- int light[M];
- int main(){
- ????int T,n,m,H,i,add,sign,t;
- ????scanf("%d",&T);
- ????while(T--){
- ????????scanf("%d%d%d",&n,&m,&H);
- ????????memset(light,0,sizeof(light));
- ????????for(i=0;i<m;i++){
- ????????????scanf("%d",&t);
- ????????????light[t]=1;
- ????????}
- ????????for(i=1;i<=n;i++){
- ????????????add=0;
- ????????????sign=1;
- ????????????while(light[i+add]==0&&abs(add)<H){
- ????????????????if(sign){
- ????????????????????if(add>=0)add++;
- ????????????????????else add--;
- ????????????????????sign=0;
- ????????????????}
- ????????????????else sign=1;
- ????????????????if(i-add>0&&i-add<=n)add=-add;
- ????????????}
- ????????????add=abs(add);
- ????????????printf("%d\n",H-add);
- ????????}
- ????}
- ????return 0;
- }
?
仔细理解题目,再思考一下,便知道,每颗植物所能成长的最大高度为 ???? H - mins(mins为离它最近光源与它的距离)。故只要能找到离第i颗植物最近的光源即可,怎么找呢?
我使用的是左右探测法(自己脑补出来的名字。。),灵感来自解决散列冲突的平方探测法,对于植物 i 我们先观察他左边 距离为1 的位置,再观察右边距离为1 的位置
如果不存在光源,再找左边距离为 2 的位置 ,依次类推,直至距离大于等于H或找到光源,若找到,则当前植物的高度即可输出,否则 植物高度为0;
惯例吐槽(之所以老在计蒜客做题有两个原因,第一,简单。。。。。(毕竟我新手),第二,有将题目合理分类,使我可针对性的练习,但是,这道题虽然被分类在二分查找,但我完全看不出哪里需要二分的说,应该是存在二分查找的解法,但我没想到,以后想到了再重新写吧(并不会),嗯,这题麻烦的地方就是左右寻找可能的越界,其他都没什么了,
如果不是这两天刚好AC了,我都觉得没必要写。。)
以上是关于计蒜客 光合作用的主要内容,如果未能解决你的问题,请参考以下文章