题目链接:https://ac.nowcoder.com/acm/contest/5929/B
把正负数分别存起来
由于在答案相同的情况下要找序号小的,所以把每个数最小的两个序号存起来
三种情况:
1.最小的两个正数
2.最大的两个负数
3.根据每个负数寻找最接近的正数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
vector<int> v1,v2;
map<int,pair<int,int> >mp;
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
if(x<0) v1.push_back(x);
else v2.push_back(x);
if(mp[x].first==0) mp[x].first=i;
else if(mp[x].second==0) mp[x].second=i;
}
sort(v1.rbegin(),v1.rend());
sort(v2.begin(),v2.end());
int ans1=0x3f3f3f3f,ans2;
if(v1.size()>1)
{
if(ans1>abs(v1[0]+v1[1]))
{
ans1=abs(v1[0]+v1[1]);
if(v1[0]==v1[1])
ans2=mp[v1[0]].first+mp[v1[0]].second;
else ans2=mp[v1[0]].first+mp[v1[1]].first;
}
}
if(v2.size()>1)
{
if(ans1>abs(v2[0]+v2[1]))
{
ans1=abs(v2[0]+v2[1]);
if(v2[0]==v2[1])
ans2=mp[v2[0]].first+mp[v2[0]].second;
else ans2=mp[v2[0]].first+mp[v2[1]].first;
}
else if(ans1==abs(v2[0]+v2[1]))
{
if(v2[0]==v2[1])
ans2=min(ans2,mp[v2[0]].first+mp[v2[0]].second);
else ans2=min(ans2,mp[v2[0]].first+mp[v2[1]].first);
}
}
if(v1.size()>0&&v2.size()>0)
{
int len=v1.size();
for(int i=0;i<len;i++)
{
//小于等于(这两个函数要求数组从小到大)
int x=upper_bound(v2.begin(),v2.end(),-v1[i])-v2.begin()-1;
//大于等于
int y=lower_bound(v2.begin(),v2.end(),-v1[i])-v2.begin();
if(x>=0&&x<v2.size())
{
if(ans1>abs(v1[i]+v2[x]))
{
ans1=abs(v1[i]+v2[x]);
ans2=mp[v1[i]].first+mp[v2[x]].first;
}
else if(ans1==abs(v1[i]+v2[x]))
{
ans2=min(ans2,mp[v1[i]].first+mp[v2[x]].first);
}
}
if(y>=0&&y<v2.size())
{
if(ans1>abs(v1[i]+v2[y]))
{
ans1=abs(v1[i]+v2[y]);
ans2=mp[v1[i]].first+mp[v2[y]].first;
}
else if(ans1==abs(v1[i]+v2[y]))
{
ans2=min(ans2,mp[v1[i]].first+mp[v2[y]].first);
}
}
}
}
printf("%d %d\n",ans1,ans2);
}
本文介绍了一种算法,用于找到数组中两数之和的最小绝对值,并记录下对应的元素位置。通过将正负数分开存储,利用排序和二分查找,实现了高效的求解。文章详细解释了算法步骤,包括处理正数、负数和正负数配对的情况。
168万+

被折叠的 条评论
为什么被折叠?



