C. Good Array
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Let's call an array good if there is an element in the array that equals to the sum of all other elements. For example, the array a=[1,3,3,7]a=[1,3,3,7] is good because there is the element a4=7a4=7 which equals to the sum 1+3+31+3+3 .
You are given an array aa consisting of nn integers. Your task is to print all indices jj of this array such that after removing the jj -th element from the array it will be good (let's call such indices nice).
For example, if a=[8,3,5,2]a=[8,3,5,2] , the nice indices are 11 and 44 :
- if you remove a1a1 , the array will look like [3,5,2][3,5,2] and it is good;
- if you remove a4a4 , the array will look like [8,3,5][8,3,5] and it is good.
You have to consider all removals independently, i. e. remove the element, check if the resulting array is good, and return the element into the array.
Input
The first line of the input contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105 ) — the number of elements in the array aa .
The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1061≤ai≤106 ) — elements of the array aa .
Output
In the first line print one integer kk — the number of indices jj of the array aa such that after removing the jj -th element from the array it will be good (i.e. print the number of the nice indices).
In the second line print kk distinct integers j1,j2,…,jkj1,j2,…,jk in any order — nice indices of the array aa .
If there are no such indices in the array aa , just print 00 in the first line and leave the second line empty or do not print it at all.
Examples
Input
Copy
5
2 5 1 2 2
Output
Copy
3
4 1 5
Input
Copy
4
8 3 5 2
Output
Copy
2
1 4
Input
Copy
5
2 1 2 4 3
Output
Copy
0
Note
In the first example you can remove any element with the value 22 so the array will look like [5,1,2,2][5,1,2,2] . The sum of this array is 1010 and there is an element equals to the sum of remaining elements (5=1+2+25=1+2+2 ).
In the second example you can remove 88 so the array will look like [3,5,2][3,5,2] . The sum of this array is 1010 and there is an element equals to the sum of remaining elements (5=3+25=3+2 ). You can also remove 22 so the array will look like [8,3,5][8,3,5] . The sum of this array is 1616 and there is an element equals to the sum of remaining elements (8=3+58=3+5 ).
In the third example you cannot make the given array good by removing exactly one element.
题意:给你一串n长度数组,然后移除一个数,问剩下的数中一个数是不是另外所有数的和,然后移除的数就叫特殊数(瞎编的叫法)。输出特殊数最多有多少个,然后再输出特殊数的位置。
样例1:移除num[1] = 2,剩下的是[5,1,2,2] 5=1+2+2,就这个意思,然后num[1] num[4] num[5]都可以,输出3和1 4 5
思路:一开始我是想用set来写的,但是一直wa24数据了。。。后面去看了一下大佬的代码才知道我这个思路就是渣渣。
大佬思路:先记录数组每个数字出现的次数和总和,然后操作
首先我们知道,在移除掉特殊数之后剩余的数组还有一个最大值。现在就有两种情况
第一种:a是数组中的最大值,意思就是a出现了两次及以上,我先移除一个a,移除后剩下的数组的最大值还是a
第二种:b是剩下的数组中的最大值,意思是假如我们移除一个数,那么剩下的数组中有一个最大值,最大值就b
其它的值就不要考虑了。。。
两种情况的结合就是:Sum(总和) = Max(剩下数组的最大值) + sum(剩下数组的和减去Max) + ans(被移除的数)
把情况带进去
第一种情况:Sum=a+a+a //因为要a是特殊数,那么sum==Max才可以
第二种情况:Sum=b+b+ans //上同
AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=200000+10;
long long int num[maxn],vis[maxn*5]; //num记录输入数组,vis记录数组中的数字出现次数
bool ans[maxn*5]; //记录是否是特殊数
long long int sum,temp,Max;
int main()
{
int n,i,k;
cin>>n;
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));sum=0;Max=0;
memset(ans,false,sizeof(ans));
for (i=1;i<=n;i++)
{
scanf("%d",&num[i]);
vis[num[i]]++; //出现一次+1
sum=sum+num[i]; //算总和
Max=max(Max,num[i]); //记录最大值,后面循环要用
}
for (i=1;i<=n;i++)
{
temp=sum-num[i]*2; //这里要减两个num[i]
if (temp==num[i]) //第一种情况
{
if (vis[num[i]]>1) //判断是不是多次出现
ans[temp]=true; //如果是,那么就是特殊数
continue;
}
if (temp>0&&temp<=1000010&&vis[temp]>0) //第二种情况
ans[temp]=true;
}
k=0;
for (i=1;i<=Max;i++)
if (ans[i]==true) //如果i是特殊数
k=k+vis[i]; //把i出现的次数都+,因为移除哪个i都可以
cout<<k<<endl;
for (i=1;i<=n;i++)
if (ans[num[i]]==true)
printf("%d ",i);
cout<<endl;
return 0;
}
......凑合用吧