构造题详解
构造题是一种较难的题型,小到csp-j,大到省选甚至国赛,都有可能考。
例题一:CF1352B
题意:
给n和k,要求构造k个数,使得这k个数的和为n,且k个数全为奇数或全为偶数。
思路:
既然要求全为奇数或全为偶数,那么就分情况讨论。
当全为奇数时,我们可以构造前k-1个数都为1。
剩下的一个数就等于n-k+1,如果满足,输出答案。
当全为偶数时,我们可以构造前k-1个数都为2。
剩下的一个数就等于n-2k+2,如果满足,输出答案。
否则,无解。
代码:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
int main() {
int t;
cin>>t;
while(t--) {
cin>>n>>k;
if ((n-k+1)%2==0&&(n-2*k+2)%2==1) {
cout<<"NO\n";
}
else if ((n-k+1)%2==0) {
if (n-2*k+2<=0) {
cout<<"NO\n";
continue;
}
cout<<"YES\n";
for (int i=1;i<k;i++) {
cout<<2<<" ";
}
cout<<n-2*k+2<<"\n";
}
else {
if (n-k+1<=0) {
cout<<"NO\n";
continue;
}
cout<<"YES\n";
for (int i=1;i<k;i++) {
cout<<1<<" ";
}
cout<<n-k+1<<"\n";
}
}
}
例题二:P1146
题意:
n个硬币,正面向上,每次反转n-1个,要求反面朝上,求最小操作次数和字典序最小的方案。
思路:
研究样例发现,答案应为n,方案为:
0111...111
1100...000 n=2时答案为2
0001...111
1111...000 n=4时答案为4
......
设目前操作数为i。
所以当目前操作数为奇数时:
0*i+1*(n-i)
否则:
1*i+0*(n-i)
代码:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
int main() {
cin>>n;
cout<<n<<"\n";
for (int i=0;i<n;i++) {
if (i%2==1) {
for (int j=0;j<=i;j++) {
cout<<1;
}
for (int j=i+1;j<n;j++) {
cout<<0;
}
}
else {
for (int j=0;j<=i;j++) {
cout<<0;
}
for (int j=i+1;j<n;j++) {
cout<<1;
}
}
cout<<"\n";
}
return 0;
}
浙公网安备 33010602011771号