昨晚真的自闭。。

C. Platforms Jumping

题意:n宽的河,m块木板,每个木板宽ci,这个人一次最远可以跳d远,问有没有可能这个人可以到达对岸(n+1处),并输出可行方案(1~n每块是水面(0),还是有第i块木板覆盖(i))。

统计木板总长数,如果木板长度加上 d * 跳的步数还是小于n,不可能到达对岸了。
否则开始贪心的放木板,这里有个值得注意的点就是,贪心贪过了最后木板出现重叠怎么办,
所有贪的时候还要注意,当前可跳过的水面总数是n-sum,贪心的同时加上这个约束条件,每次减去已跳过的水面数即可。
int main()
{
    ll n, m, d;
    rd(n),rd(m),rd(d);
    ll c[m],sum = 0;
    for(int i = 0; i < m; i++)
        rd(c[i]),sum += c[i];
    if(sum + (d - 1) * (m + 1) < n)
    {
        cout << "NO\n";
        return 0;
    }
    cout << "YES\n";
    ll z = n - sum;//空了多少水面w
    int a[n] = {0};
    int pos = 0;
    for(ll i = 0; i < m; i++)
    {
        pos += min(d - 1, z);//每次贪心跳过最多可使用的空水面
        for(ll j = pos; j - pos < c[i]; j++)  a[j] = i + 1;
        z -= min(z, d - 1);
        pos += c[i];
    }
    for(int i = 0; i < n; i++)
        cout << a[i] << ' ';
    return  0;
}
D. Binary String Minimizing
题意:可以交换最多k次相邻数字,问你最后能得到的字典序最小的字符串
例:
8 5
11011010
01011110
对于某组交换的结果,肯定是一个0跨越一串1到达这一串1的尽量左侧
所有考虑交换时只考虑0要和前面哪个1交换(0插到这一串1的最左侧还是插到1中间某位置)而不是挨个swap。(因为题目只有0和1,每个1都是等价的,所有0和这串1的哪个都可以直接换)
每次记录当前0之前的一串1的最左侧位置在哪里。
这种写法就比较神奇。
两种情况,可以到达最左侧。
11110  ——>  01111,新的最左侧肯定是原来的j+1
第二种情况,无法到达最左侧
11110 ——>11011,那么再之后一次也不能换了,这时候 j 在哪都无所谓了。

关键在于想到维护此刻0前一整串1的最左侧
int main ()
{
    int t;rd(t);
    while (t--)
    {
    	ll n,k;rd(n),rd(k);
        string str;cin>> str;
        ll j = 0;
        for (ll i = 0; i < n; i++)
        {
            if(str[i] == '0')
            {
                ll l = min(i - j, k);
                swap(str[i], str[i - l]);
                k = k - l;
                j++;
            }

        }
        cout << str << "\n";
    }
}