S + T
时间限制:1000 ms | 内存限制:65535 KB
难度:2
- 描写叙述
-
给你一个长度为n的整数序列A1。A2,……,An,找出两个整数Ai和Aj(i<j),使得Ai-Aj尽量大。
- 输入
- 输入第一行为数据组数T(T<=100)。
每组数据的第一行为整数的个数n(2<=n<=100000);一下n行。每行为一个绝对值不超过150000的正整数。
(全部的数据都不超过2^64 - 1)
- 输出
- 对于每组数据,输出Ai –Aj的最大值、i值和j值。(假设有多个最大值,则输出先出现的最大值和i,j值)
- 例子输入
-
235 2 162 3 6 2 1 -1
- 例子输出
-
4 1 37 3 6
- 提示
- 假设你觉得数据太大,则本OJ推荐使用long long
- 来源
- 算法入门
- 上传者
刚開始用的结构体优先队列,结果发现wa了几次才发现,i>j...也就是说前面的数减去后面数的最大值。
想想还是把wa的贴出来吧。AC贪心策略是,先把数据用数组保存起来。然后for循环从0-n筛选最大值,保存起来,从n-0筛选最小值,保存起来。
最后再用一个for循环寻找差的最大值。详细看以下ac代码。
wa:
#include <stdio.h> #include <queue> using namespace std; struct node { long long t,num; bool operator<(const node &a)const { if(num<a.num) return true; else if(num==a.num&&t<a.t) return true; else return false; } }; priority_queue<node>s; int main() { long long ncase,mark1,mark2,sum,n,mark; node x,y1,y2,temp; scanf("%lld",&ncase); while(ncase--) { scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%lld",&x.num); x.t=i; s.push(x); } y1=s.top(); while(s.size()>1) { temp=s.top(); if(temp.num!=y1.num) break; else mark=temp.t,s.pop(); } while(s.size()>1) s.pop(); y2=s.top(),s.pop(); printf("%lld",y1.num-y2.num); if(y1.num!=y2.num) printf(" %lld %lld ",mark,y2.t); else printf(" 1 2 "); } return 0; }
ac:
#include <stdio.h> #include <string.h> #define N 100005 long long num[N]; struct node { long long max,t1,min,t2; }c[N]; int main() { long long t,n,temp,mark1,mark2; scanf("%lld",&t); while(t--) { memset(num,0,sizeof(num)); memset(&c,0,sizeof(&c)); scanf("%lld",&n); temp=-150005; for(int i=0;i<n;i++) { scanf("%lld",&num[i]); if(temp<num[i]) temp=num[i],mark1=i+1; c[i].max=temp; c[i].t1=mark1; } temp=150005; for(int i=n-1;i>=0;i--) { if(num[i]<=temp) temp=num[i],mark2=i+1; c[i].min=temp; c[i].t2=mark2; } temp=-150005*2; for(int i=0;i<n-1;i++) { if(temp<c[i].max-c[i+1].min) temp=c[i].max-c[i+1].min,mark1=c[i].t1,mark2=c[i+1].t2; } printf("%lld %lld %lld ",temp,mark1,mark2); } return 0; }