当一个数组中的某个元素值等于其他所有元素的和,我们称这个数组是“优秀”的。比如[1,3,3,7],是优秀的,因为7=1+3+3。
给你一个包含 n 个元素的数组 a ,对于某一个下标 j (1<=j<=n),当删除这个元素后,可能使新的数组变为“优秀”的。比如[1,3,3,1,7],当删除a[1]或者a[4]时,这个数组就是“优秀”的,你的任务是找到所有满足条件的下标 j 。
注意:每次删除都是独立的,每次删除都是由n个元素变为n-1个元素。
Input
第一行包含一个整数 n(2<=n<=2e5),表示数组a的元素个数。
第二行包含n个由空格分隔的整数a[i](1<=a[i]<=10^6).
Examples
Input
5
2 5 1 2 2
Output
3
1 4 5
Input
4
8 3 5 2
Output
2
1 4
Input
5
2 1 2 4 3
Output
0
这一题很巧妙
我们将每一个数出现的个数用visited数组保存下来,要删除的数用ans[number]来记录,
那么Sum=ans+number1+res,按照题目要求,res=number1。因而Sum=ans+2*number1
我们是根据判断Sum-2*number所得数temp是否在集合中来判断temp是否可以去除
则此时会出现两种情况1.ans=number1 2.ans!=number1
第一种情况:
我们观察三个例子{3,2,5,1,2,2} ,{5,5,1,2,2},{5,5,5}
当number1=5时,则temp=5,则此时5=2+3,不是一个单独的元素,不符合题意,应符合的是第二种情况,因此想要排除第一种情况,就需要判断5是不是出现2次及以上,如果出现2次及以上,则一定满足,则可以将5纳入可删除序列
第二种情况:
直接判断temp是否出现在集合中即可,即visited[temp]是否大于0
用Max记录最大值,这样可以直接计算需要被删除元素出现的个数,而不需要完全遍历遍,适当的优化
#include<bits/stdc++.h>
int const num=2e5+20;
using namespace std;
long long a[num];
long long visited[num*5];
bool ans[num*5];
int main()
{
long long n;
scanf("%lld",&n);
memset(a,0,sizeof(a));
memset(visited,0,sizeof(visited));
memset(ans,false,sizeof(ans));
long long sum=0,temp,Max=0,res=0;
for(long long i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
Max=max(Max,a[i]);
visited[a[i]]++;
}
for(int i=0;i<n;i++)
{
temp=sum-a[i]*2; //temp为被删除元素
if(temp==a[i]) //第一种情况
{
if(visited[temp]>1)
ans[temp]=1;
continue;
}
if(temp>0&&temp<=1e6+20&&visited[temp]>0) //第二种情况
ans[temp]=1;
}
for(int i=1;i<=Max;i++)
{
if(ans[i])
res+=visited[i];
}
cout<<res<<endl;
for(int i=0;i<n;i++){
if(ans[a[i]])
printf("%d ",i+1);
}
cout<<endl;
return 0;
}
当中