20250731 构造总结

构造你值得拥有

构造题是比赛中常见的一类题型。

从形式上来看,问题的答案往往具有某种规律性,使得在问题规模迅速增大的时候,仍然有机会比较容易地得到答案。

这要求解题时要思考问题规模增长对答案的影响,这种影响是否可以推广。例如,在设计动态规划方法的时候,要考虑从一个状态到后继状态的转移会造成什么影响。

构造的特点

构造题一个很显著的特点就是高自由度,也就是说一道题的构造方式可能有很多种,但是会有一种较为简单的构造方式满足题意。看起来是放宽了要求,让题目变的简单了,但很多时候,正是这种高自由度导致题目没有明确思路而无从下手。

构造题另一个特点就是形式灵活,变化多样。并不存在一个通用解法或套路可以解决所有构造题,甚至很难找出解题思路的共性。

对于一些比较容易写出小范围暴力的构造题,在比赛时如果时间充足可以考虑打表观察规律。

构造的例题

给定一个长度为 nnn、元素由 000111 组成的数组。

现在可以选择若干(可以为 000)个值为 000 的元素,将其修改为 111

记:xxx 为数组中最长连续 111 子段的长度(规定,若所有数均为 000,则 xxx000);yyy 为修改的元素的个数。

求要怎么修改才能使 x−yx−yxy 最大,并构造一个方案(输出修改后的数组)。

每次只要枚举查看左边和右边是否有111,有的话就把当前下标设为111,然后yyy++。

#include<bits/stdc++.h>
using namespace std;
bool f[100005];
int main(){
    int t;
    cin>>t;
    while(t--){
        memset(f,0,sizeof f);
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>f[i];
        }
        int y=0;
        for(int i=1;i<=n;i++){
            if(!f[i]&&(f[i-1]||f[i+1])){
                f[i]=1;
                y++;
            }
        }
        int mx=0,cs=0;
        for(int i=1;i<=n;i++){
            if(f[i]){
               cs++;
            }else{ 
                cs=0;
            }
            mx=max(mx,cs);
        }
        cout<<mx-y<<endl;
        for(int i=1;i<=n;i++){
            cout<<f[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值