题目描述
输入描述
输出描述
输入样例
4
3
12 16 14
1
1
3
1 2 3
6
81 75 75 93 93 87
输出样例
YES
3 1 3
YES
1
NO
YES
5 5 4 1 4 5
样例解释
像极了初中数学题,尝试了用数学解题方法成功解出了每一项,但是过程真复杂(摔桌)
解读题意后可以列出测试数据 1 中数组 b 的组成公式,即
b [ 1 ] = a [ 1 ] + 3 ∗ a [ 2 ] + 2 ∗ a [ 3 ] b [1]=a[1]+3*a[2]+2*a[3] b[1]=a[1]+3∗a[2]+2∗a[3],
b [ 2 ] = 2 ∗ a [ 1 ] + a [ 2 ] + 3 ∗ a [ 3 ] b[2]=2*a[1]+a[2]+3*a[3] b[2]=2∗a[1]+a[2]+3∗a[3],
b [ 3 ] = 3 ∗ a [ 1 ] + 2 ∗ a [ 2 ] + a [ 3 ] b[3]=3*a[1]+2*a[2]+a[3] b[3]=3∗a[1]+2∗a[2]+a[3].
发现 : 数 组 b 的 总 和 为 n ∗ ( n + 1 ) 2 ∗ 数 组 a 之 和 数组 b 的总和为 \frac{n*(n+1)}{2}*数组 a 之和 数组b的总和为2n∗(n+1)∗数组a之和
而通过 s u m − b [ i ] + b [ ( i − 1 + n ) % n ] sum-b[i]+b[(i-1+n)\%n] sum−b[i]+b[(i−1+n)%n] 可以得到 a [ i ] ∗ n a[i]*n a[i]∗n 的值(此处 sum 为数组 a 之和)
判断各项是否合法即可。
参考代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+10;
int b[N];
int a[N];
int main(){
int t;
cin>>t;
while(t--){
ll n;
cin>>n;
ll sum=0;
int flag=0;
for(int i=0;i<n;i++){
cin>>b[i];
sum+=b[i];
}
ll nn=n*(n+1)/2;
if(sum%nn){
cout<<"NO"<<endl;
continue;
}
sum/=nn;//数组a的加和
for(int i=0;i<n;i++) {
ll f=sum-b[i]+b[(i-1+n)%n];//规律
//cout<<"f="<<f<<endl;
if(f<=0||f%n>0){
cout<<"NO"<<endl;
flag=1;
break;
}
a[i]=f/n;
}
if(flag)
continue;
cout<<"YES"<<endl;
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
return 0;
}