CodeCraft-22 and Codeforces Round 795 (Div. 2)C. Sum of Substrings(分类讨论、贪心)
感觉分类讨论的能有点弱。遇到复杂一点的分类讨论的题目,代码就写的巨长。
首先观察到处在中间位置的1对答案的贡献是11,具体在中间哪个位置是没有关系的。
只有两端的两个位置是比较特殊的
所有我们考虑将最左端第一次出现的1放到1位置
将最右端第一次出现的1放到n的位置。
贪心的考虑,如果能进行第二个操作我们优先进行第2个操作,因为我们希望答案最小,不能进行第2个操作的情况下我们进行第1种操作。
代码很丑
#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define ls p<<1
#define rs p<<1|1
#define pii pair<int, int>
#define pll pair<long long, long long>
#define ll long long
#define ull unsigned long long
#define db double
#define endl '\n'
#define debug(a) cout<<#a<<"="<<a<<endl;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define INF 0x3f3f3f3f
#define x first
#define y second
#define pb push_back
using namespace std;
const int N=2e5+10;
char a[N];
void solve()
{
int n,k;cin>>n>>k;
cin>>(a+1);
int l1=1,r1=n,cnt=0;
rep(i,1,n) if(a[i]=='1') cnt++;
//找左边第1个1的位置
rep(i,1,n) if(a[i]=='1')
{
l1=i;
break;
}
//找右边第一个1的位置
fep(i,n,1) if(a[i]=='1')
{
r1=i;
break;
}
if(cnt==0)
{
cout<<0<<endl;
return;
}
//只有1个1
else if(cnt==1)
{
int dl=l1-1,dr=n-r1;
//先判是否能道右边
if(k>=dr)
{
cout<<1<<endl;
return;
}
//左边
if(k>=dl)
{
cout<<10<<endl;
return;
}
else out<<11<<endl;
}
else
{
int dl=l1-1,dr=n-r1;
int ans=11*cnt;
//先判是否能到右边
if(k>=dr) ans-=10,k-=dr;
//左边
if(k>=dl) ans-=1;
cout<<ans<<endl;
}
}
signed main()
{
IOS
// freopen("1.in", "r", stdin);
int _;
cin>>_;
while(_--)
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署