蒟蒻的第一篇题解。
这个题还是特别水的,但我就被淹死了 。
读题
给了你一个数组,让你将其中一个数的一部分给另一个数,使所有数相等,只操作一次。当我们一看到只操作一次 ,就会很自然而然地想到:
就只有两个数不一样。
所以我们就可以在这里下功夫。
而改变之后所有数相同,所以平均数就是所有数的数值。
所以出现最多的数一定与平均数相同 ,并且,如果可以移动,剩下的两个数的平均数也一定与之相同 。
我们就可以先判断整个数组的和能不能被数组大小 $n$ 整除,如果能,证明所有数的平均数就是 $sum/n$,如果不能的话操作一定不成立
如果平均数可以求出,那么这一组数就可以用多次操作使所有数相同。
那怎样才能判断操作一次呢?
操作一次只能改变两个数,那么与出现最多的数不同的数只能有两个。
那怎么判断这些数中出现最多的数的呢?
我们会首先想到桶排。也不是不行,就是太浪费了,并且这水题也不足以用桶排,我们就又想起刚刚想到的:
只有两个数不一样,其他数都等于平均数 ,所以我们只需要统计与平均数不同的个数即可。
之后按照题目要求给出输出即可,千万别打错了。
$code$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include<iostream> using namespace std; int f[1001]; int flag; struct node{ int num; int data; }; node maxn,minn={0,0x3f3f3f}; int sum; int main(){ int n; cin>>n; for(int i=0;i<n;i++){ cin>>f[i]; sum+=f[i]; if(maxn.data<f[i]){ maxn.data=f[i]; maxn.num=i; } if(minn.data>f[i]){ minn.data=f[i]; minn.num=i; } } if(sum%n!=0) { cout<<"Unrecoverable configuration."; return 0;} else{ int pj=sum/n; for(int i=0;i<n;i++){ if(f[i]!=pj) flag++; } if(flag==0) { cout<<"Exemplary pages.\n"; return 0;} else if(flag>2) { cout<<"Unrecoverable configuration.\n"; return 0;} else{ printf("%d ml. from cup #%d to cup #%d.\n",(maxn.data-minn.data)/2,minn.num+1,maxn.num+1); return 0; } } return 0; }
|