构造题详解

构造题是一种较难的题型,小到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;
}
posted on 2026-01-09 18:58  hyh0926  阅读(11)  评论(0)    收藏  举报