Re0(学长在2017新年出的题)
2017-08-06 20:18
176 查看
Problem Description
Re0 虽然是老套的穿越剧情,但是却有着虐男主 (486) 的新奇点子。作为 2016 最火的番,我们来统计一下其中每个人能看到的对手的人数吧。
对于当前的人,他只能看见战力从他依次增高的一个阶梯。譬如说对于战力分别为 6, 5, 1, 2, 3, 4, 0 的一个分布来说,第一个向前看去看到的对手人数为 0,第二个向前看去能看到战力为 6 的人,看到的对手人数为 1,第三个向前看去能看到战力为 6, 5 的 2 人,第四个向前看去能看到战力为 6, 5 的 2 人,第五个向前看去能看到战力为 6, 5 的 2 人,第六个向前看去能看到战力为 6, 5 的 2 人,第七个向前看去能看到战力为 4, 5, 6 的 3 人。而战力为 1, 2, 3 的人会被战力为 4 的人所屏蔽掉。
Input
输入数据有多组(数据组数不超过 20),到 EOF 结束。
对于每组数据:
•第一行输入一个整数 n, m 表示要统计的总人数和询问的次数。
•接下来一行有 n 个以空格分隔的正整数,表示 n 个人的战力分布。
•接下来 m 行,每行一个正整数 pos,表示要询问的人的位置,位置标号按照输入从 1~n。
数据范围:1 <= n, m <= 100000,战力范围为 1~1000。
Output
对于每组数据中的每次询问,输出一个正整数表示此人向前看去能够看到的对手(威胁)数。
Example Input
7 7
6 5 1 2 3 4 0
1
2
3
4
5
6
7
Example Output
0
1
2
2
2
2
3
Hint
Author
「SDUT Round #2 - 2017 新春大作战」UMR
Think: 一道普通栈的题。。。思考一下如何对战力高低出栈、入栈就解决问题了(读题,从本位置开始递增。。。)。直接暴力循环过的想法有点天真(出题的学长呵呵一笑)2333。看透题意后,说白了就是求每个位置,从左边看,能看到比当前位置战力高的递增战力的数目(从栈底到栈顶,战力递减的长度)。
直接上C的代码:
Re0 虽然是老套的穿越剧情,但是却有着虐男主 (486) 的新奇点子。作为 2016 最火的番,我们来统计一下其中每个人能看到的对手的人数吧。
对于当前的人,他只能看见战力从他依次增高的一个阶梯。譬如说对于战力分别为 6, 5, 1, 2, 3, 4, 0 的一个分布来说,第一个向前看去看到的对手人数为 0,第二个向前看去能看到战力为 6 的人,看到的对手人数为 1,第三个向前看去能看到战力为 6, 5 的 2 人,第四个向前看去能看到战力为 6, 5 的 2 人,第五个向前看去能看到战力为 6, 5 的 2 人,第六个向前看去能看到战力为 6, 5 的 2 人,第七个向前看去能看到战力为 4, 5, 6 的 3 人。而战力为 1, 2, 3 的人会被战力为 4 的人所屏蔽掉。
Input
输入数据有多组(数据组数不超过 20),到 EOF 结束。
对于每组数据:
•第一行输入一个整数 n, m 表示要统计的总人数和询问的次数。
•接下来一行有 n 个以空格分隔的正整数,表示 n 个人的战力分布。
•接下来 m 行,每行一个正整数 pos,表示要询问的人的位置,位置标号按照输入从 1~n。
数据范围:1 <= n, m <= 100000,战力范围为 1~1000。
Output
对于每组数据中的每次询问,输出一个正整数表示此人向前看去能够看到的对手(威胁)数。
Example Input
7 7
6 5 1 2 3 4 0
1
2
3
4
5
6
7
Example Output
0
1
2
2
2
2
3
Hint
Author
「SDUT Round #2 - 2017 新春大作战」UMR
Think: 一道普通栈的题。。。思考一下如何对战力高低出栈、入栈就解决问题了(读题,从本位置开始递增。。。)。直接暴力循环过的想法有点天真(出题的学长呵呵一笑)2333。看透题意后,说白了就是求每个位置,从左边看,能看到比当前位置战力高的递增战力的数目(从栈底到栈顶,战力递减的长度)。
直接上C的代码:
#include<stdio.h> #include<string.h> #include<malloc.h> #define MAX 100100 //已知数据范围 typedef int Elem; typedef struct { int base; //栈底 int top; //栈顶(实际上是+1了) Elem *data; //战力 int length; //栈的长度 int size; //栈开辟的空间大小(和之前我发的栈一样,因为没有数据卡,就没有当空间不够时动态增加新空间) }stack; void Init(stack *s); //初始化栈 void Push(stack *s, int k); //入栈 void Pop(stack *s); //弹出栈顶 int Empty(stack *s); //判断栈是否为空 int Gettop(stack *s); //返回栈顶元素 int main() { int n, m; while(scanf("%d %d", &n, &m) != EOF){ stack s; //定义栈s Init(&s); //初始化栈 int i, k, h, a[100100]; memset(a, 0, sizeof(a)); //用来存第i个位置可以看到的对手数,方便询问操作,直接拿来输出 for(i = 1; i <= n; i++){ scanf("%d", &k); //战力值 if(Empty(&s)){ //如果当前栈为空直接入栈 a[i] = s.length; //入栈前,该位置可以看见的对手数 Push(&s, k); //入栈 } else{ //这个else是本题的代码精化部分~ while(!Empty(&s)){ //如果栈不空 h = Gettop(&s); //栈顶的战力值 if(k >= h){ //如果当前位置的战力大于等于栈顶的战力,弹出栈顶,应为要求从当前位置向左看 Pop(&s); //可以看见的递增战力(很好理解吧O(∩_∩)O哈哈~) } else{ //当小于栈顶的战力就入栈(所以栈其实是一个递减的战力分布) a[i] = s.length; //本位置入栈前,本位置望左看,可以看见的递增战力的数目 Push(&s, k); break; //操作完成后就退出循环嘛(其实一开始自己漏了2333) } } if(Empty(&s)){ //本题的隐藏关键(特殊情况),本位置的战力高于左边所有的战力!!!还好傻傻的自己在Wrang Answer后机智地想到了这点 a[i] = s.length; Push(&s, k); } } } for(i = 1; i <= m; i++){ scanf("%d", &k); //要询问的位置 printf("%d\n", a[k]); } } return 0; } void Init(stack *s) { s->data = (Elem *)malloc(MAX * sizeof(Elem)); if(!s->data) exit(0); s->top = s->base = 1; s->size = MAX; s->length = 0; } void Push(stack *s, int k) { s->data[s->top++] = k; s->length++; } void Pop(stack *s) { s->top--; s->length--; } int Gettop(stack *s) { return s->data[s->top - 1]; } int Empty(stack *s) { if(s->top == s->base) return 1; return 0; }
相关文章推荐
- 2017新年启程
- WHCTF 2017 逆向题 CRACKME、BABYRE、EASYHOOK 的解题思路
- 2017新年计划
- ICCV 2017 Tutorial on Instance-level Visual Recohnition(slide1 introduction)
- 2017 新年新气象 ;)
- re:Invent 2017的四个侧面,感受中美云计算生态
- 无忧保新年攻坚首战告捷 2017开启胜利新篇章
- Subject: Re: CVE-2017-7692: Squirrelmail 1.4.22 Remote Code Execution
- 【新年新气象】——送给2017的第一天
- 2017新年规划
- 2017新年启程
- 2017新年小目标
- 2017 —— 新年计划
- 2017新年启程
- 2017新年英文好歌极力推荐《Raindrops》——中文《雨滴》
- 2017新年展望
- 2017新年启程
- cvpr 2017 re-id papers
- 2017新年总结
- 2017,新年