Problem Description
对于包含n(1<=n<=100000)个整数的序列,对于序列中的每一元素,在序列中查找其位置之后第一个大于它的值,如果找到,输出所找到的值,否则,输出-1。
Input
输入有多组,第一行输入t(1<=t<=10),表示输入的组数;
以后是 t 组输入:每组先输入n,表示本组序列的元素个数,之后依次输入本组的n个元素。
Output
输出有多组,每组之间输出一个空行(最后一组之后没有);
每组输出按照本序列元素的顺序,依次逐行输出当前元素及其查找结果,两者之间以-->间隔。
Sample Input
2
4 12 20 15 18
5 20 15 25 30 6
Sample Output
12-->20
20-->-1
15-->18
18-->-1
20-->25
15-->25
25-->30
30-->-1
6-->-1
由于这个题只给了0.15s的时间以及1e6的数据,只能用栈来实现。
为何用栈呢?由于题意中说明是当前数字-->第一个比当前大的数字,也就是相当要求一个存储结构里,当前某个数字要大于它的尾部数字,然后把尾部数字逐出,否则的话就把这个数字从尾部存入并继续下一步。尾进尾出的结构自然就是栈(双端队列过于麻烦),所以在这里用栈模拟整个过程。
整个模拟过程是:对于每个输入的数字,如果栈是空的,直接把这个数字压入栈中。如果不是空栈,则多次判断当前数字是否比栈顶数字要大,如果成立就把栈顶数字逐一驱逐,并记录栈顶数字所对于的数字为当前数字。当条件不成立是把当前数字压入栈中。当输入结束,还在栈中的数字自然就不存在既在他后边又比它大的数据了,所以一一记录其对应值为-1即可。
由于输出的时候需要依据输入的顺序,所以这里首先需要一个结构体来存储输入时的下标以及这个数字的值,记录栈顶数字的对应值时需要用到下标(否则的话记录无效,我也不知道为什么)。
所以有如下思路:
- 构建一个满足需求的结构体
- 对于每一次输入,就要比较当前数字和栈顶数字的大小关系并进行操作
- 当输入结束(如果你是一次输入操作一次的话),对还在栈中的数字进行处理
- 注意题给中的格式要求
代码如下:(请注意修改输入函数scanf_s与输出函数printf_s)
#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#define lldin(a) scanf_s("%lld", &a)
#define println(a) printf("%lld\n", a)
#define reset(a, b) memset(a, b, sizeof(a))
const int INF = 0x3f3f3f3f;
using namespace std;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1000000007;
const int tool_const = 19991126;
const int tool_const2 = 33;
inline ll lldcin()
{
ll tmp = 0, si = 1;
char c;
c = getchar();
while (c > '9' || c < '0')
{
if (c == '-')
si = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
tmp = tmp * 10 + c - '0';
c = getchar();
}
return si * tmp;
}
///Untersee Boot IXD2(1942)
/**Although there will be many obstructs ahead,
the desire for victory still fills you with determination..**/
/**Last Remote**/
struct tmp
{
ll first, second, id;//数字值,对应值,下标
}tmps[100100];
stack<tmp>sta;
int DETERMINATION()
{
ll t;
cin >> t;
for (int p = 0; p < t; p++)
{
ll n, cnt = 0;
lldin(n);
reset(tmps, 0);
for (int i = 1; i <= n; i++)
{
lldin(tmps[i].first);
tmps[i].id = i;//记录下标
if (sta.empty())
sta.push(tmps[i]);//如果是空栈,直接压栈就行
else
{
while (sta.empty()==false&&sta.top().first <tmps[i].first)
{
tmps[sta.top().id].second = tmps[i].first;
sta.pop();
}//与栈顶数字比较大小,进行操作(必须对栈是否为空进行判断,否则极易栈内越界导致错误)
if (sta.empty()||sta.top().first >= tmps[i].first)
sta.push(tmps[i]);
}
}
while (sta.empty() == false)
{
tmps[sta.top().id].second = -1;
sta.pop();
}//操作留存栈内的数字
for (int i = 1; i <= n; i++)
{
printf_s("%lld-->%lld\n", tmps[i].first, tmps[i].second);
}
if (p != t - 1)//注意格式
printf_s("\n");
}
return 0;
}