https://acm.bnu.edu.cn/v3/statments/***2016.pdf
题意:给定a数组和b数组。求c数组要求c[k]=max(a[i]+b[j])其中i+j==k||i+j==k+n
做法:一直在想如何降低时间复杂度未果,看了Ac代码觉得似曾相识??
由于要凑数嘛,而且尽量a[i]+b[j]的值比较大,比赛的时候推导出我可以设a'[i] b'[j]是之前那两个数组下标和值调换过来,那么就是求两个和等于给定值k时,下标和的最大值i。枚举下标和,ans[k]=i表示欲求的数组,用不着跑很多数字就可以求出来啦
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int id,value;
}a[200009],b[200009];
bool cmp(node x,node y)
{
return x.value<y.value;
}
int n;
int ans[200009];
int main()
{
//freopen("cin.txt","r",stdin);
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].value);
a[i].id=i;
}
for(int i=0;i<n;i++)
{
scanf("%d",&b[i].value);
b[i].id=i;
}
sort(a,a+n,cmp);
sort(b,b+n,cmp);
memset(ans,-1,sizeof(ans));
int tot=0;
for(int i=2*n-2;i>=0;i--)
{
for(int j=n-1;j>=0&&i-j<=n-1&&i-j>=0;j--)
{
int k=(a[j].id+b[i-j].id)%n;
if(ans[k]==-1)
{
ans[k]=i;
// printf("k=%d,i=%d\n",k,ans[k]);
tot++;
if(tot==n)break;
}
}
if(tot==n)break;//must!!!这个错误很脑残啊,
//这句话怎么能不写呢==取模可以不优化,也可以不用函数
}
for(int i=0;i<n-1;i++)printf("%d ",ans[i]);
printf("%d\n",ans[n-1]);
}
return 0;
}