您的位置:首页 > 其它

nyoj847 S + T(贪心)

2016-04-01 09:06 204 查看
题目847
题目信息
执行结果
本题排行
讨论区

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来源算法入门上传者
ACM_钟诗俊

刚開始用的结构体优先队列,结果发现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\n",mark,y2.t);
else
printf(" 1 2\n");
}
return 0;
}


ac:

#include <stdio.h>
#include <string.h>
#define N 100005
long long num
;
struct node
{
long long max,t1,min,t2;
}c
;
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\n",temp,mark1,mark2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: