题目链接
如果数组中有一个元素等于所有其他元素的和,那么我们称之为一个好数组。例如,数组a=[1,3,3,7]是一个好数组,因为元素a4=7,等于和1+3+3。
现在给出一个由n个整数组成的数组a。您的任务是打印这个数组所有的可删除的数字。即删除这个元素后,剩余元素组成的数组是一个好数组。
例如,如果a=[8,3,5,2],我们可以删除a1和a4,数组将分别变成[3,5,2] [8,3,5],它们都满足一个好数组的条件。
你必须独立考虑所有的移除,每删除一个元素,检查得到的数组是否是好数组,并将该元素的位置输出。
Input
第一行一个数n (2≤n≤2⋅10^5),代表数组元素的个数。
第二行输入n个数字a1,a2,…,an(1≤ai≤10^6) ,代表数组内的元素。
Output
第一行输出满足题目要求的数字个数k。
第二行输出这k个数字在数组中的位置。
如果没有满足题目要求的数字,则输出0。
样例:
input
5
2 5 1 2 2
output
3
4 1 5
input
4
8 3 5 2
output
2
1 4
input
5
2 1 2 4 3
output
0
方便起见,我们称一个好数组中的最大值为该数组中的领头元素(瞎编的)。
-
首先能想到的是,我们删除一个元素之后剩余元素的值之和(除最大值之外)肯定等于这个数组中的最大值(所以我感觉这个最大值有点像领头的一样)。
-
但是有另一种情况,我们可以删除数组中最大的元素,然后剩余元素的领头元素是原数组中的次大值,比如8 3 5 2这个样例,我们删除最大值8之后,剩下的3 5 2仍然可以组成一个以5为领头元素的好数组。
#include<stdio.h>
int main()
{
int n,a[210000],b[210000],top=0,flag,i;
long long int sum=0,max=0;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
sum+=a[i];
if(a[i]>max) //找最大值
{
max=a[i];
flag=i; //标记这个最大值,因为我们可能要删除它,
}//而且还有另一个用途,下面会写到
}
sum-=max; //下面的思路是我们把最大值先去掉,然后遍历
long long int nmax=0;//数组看看删除哪一个值之后的和与最大
for(i=1; i<=n; i++)//相等
{
if(i!=flag) //另一个用途,避免最大值进入循环
{
if(a[i]>nmax)//我们可以在遍历的过程中找到次大值
{
nmax=a[i];
}
if(max==sum-a[i])//这里是判断删除这个值之后是否满
{ //足我们上面说的
b[top++]=i;
}
}
}
if(nmax==sum-nmax)//这里判断是否是次大值为领头元素,即
b[top++]=flag;//删掉了最大值
printf("%d\n",top);
for(i=0; i<top; i++)
{
printf("%d ",b[i]);
}
return 0;
}