题意
要求构造一个长度为 n 的一个数组 a,满足以下条件:
- i=1∑nai1=1
- a 中的元素各不相同
- 1≤ai≤109
题解
利用 k(k+1)1=k1−k+11 可以进行构造:1×21,2×31,⋯(n−1)×n1,n1。但是,n1 有可能和前面某一项重复,即 n=k×(k+1)。
此时,我们构造 a=(2,2a1′,2a2′,⋯,2an−1′),其中 ai′ 为 n−1 时的解,容易验证它是符合限制的。
可能会有人问为什么不直接都采取第二种构造方式。原因是它的增长速度太快,会超出 109 的范围。而能表示成 k×(k+1) 的数是不连续的,所以上述构造方式可以保证 ai 在限制范围内。
代码
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
| #include <bits/stdc++.h> using namespace std; vector<int> v[505]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); for(int i=3;i<=500;i++) { bool ok=1; for(int k=1;k<i;k++) { v[i].push_back(k*(k+1)); if(i==k*(k+1)) ok=0; } if(ok) v[i].push_back(i); else { v[i].clear(); v[i].push_back(2); for(int k=0;k<i-1;k++) v[i].push_back(2*v[i-1][k]); } } int t;cin>>t; while(t--) { int n;cin>>n; if(n==1) { cout<<"Yes"<<'\n'; cout<<1<<'\n'; } else if(n==2) cout<<"No"<<'\n'; else { cout<<"Yes"<<'\n'; for(int i=0;i<n;i++) cout<<v[n][i]<<" \n"[i==n-1]; } } return 0; }
|