感觉分类讨论的能有点弱。遇到复杂一点的分类讨论的题目,代码就写的巨长。
首先观察到处在中间位置的1对答案的贡献是11,具体在中间哪个位置是没有关系的。
只有两端的两个位置是比较特殊的
\(1位置处的1对答案的贡献是10\)
\(2位置处的1对答案的贡献是1\)
所有我们考虑将最左端第一次出现的1放到1位置
将最右端第一次出现的1放到n的位置。
贪心的考虑,如果能进行第二个操作我们优先进行第2个操作,因为我们希望答案最小,不能进行第2个操作的情况下我们进行第1种操作。
\(操作完后如果1位置能有1我们就将答案-1\)
\(如果n位置能有1我们就将答案-10\)
代码很丑\(qwq\)
#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;
}
标签:CodeCraft,cout,22,Sum,位置,long,答案,dr,define
From: https://www.cnblogs.com/cxy8/p/18005962