Codeforces Round #598 (Div. 3)改题

C. Platforms Jumping

There is a river of width n. The left bank of the river is cell 0 and the right bank is cell n+1 (more formally, the river can be represented as a sequence of n+2 cells numbered from 0 to n+1). There are also m wooden platforms on a river, the i-th platform has length ci (so the i-th platform takes ci consecutive cells of the river). It is guaranteed that the sum of lengths of platforms does not exceed n.

You are standing at 0 and want to reach n+1 somehow. If you are standing at the position x, you can jump to any position in the range [x+1;x+d]. However you don’t really like the water so you can jump only to such cells that belong to some wooden platform. For example, if d=1, you can jump only to the next position (if it belongs to the wooden platform). You can assume that cells 0 and n+1 belong to wooden platforms.

You want to know if it is possible to reach n+1 from 0 if you can move any platform to the left or to the right arbitrary number of times (possibly, zero) as long as they do not intersect each other (but two platforms can touch each other). It also means that you cannot change the relative order of platforms.

Note that you should move platforms until you start jumping (in other words, you first move the platforms and then start jumping).

For example, if n=7, m=3, d=2 and c=[1,2,1], then one of the ways to reach 8 from 0 is follow:

The first example: n=7.
在这里插入图片描述
在这里插入图片描述

题意:

   一个人要从0到N+1,同时这里有M块木板,他们的长度在输入的第二行给出,
此时这个人每次跳跃的长度为D,问能不能通过移动木块的位置,到达N+1

思路

   贪心的思想,将最理想的情况列举出来,但是因为木块不能相交,所以我们
要根据实际情况进行修改;
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3+100;
int a[maxn] , l[maxn] ,ans[maxn];
int main()
{
    int n , m , d;
    cin >> n >> m >> d;
    for(int i=0;i<m;i++)cin >> a[i];
 
    int r = 0;
    for(int i=0;i<m;i++)
    {
        r +=d;
        l[i] = r;
        r += a[i]-1;
    }
    r += d;
    l[m] = n+1;
    if(r<=n)
    {
        cout <<"NO"<<endl;
        return 0;
    }
    cout <<"YES"<<endl;
    for(int i = m-1;i>=0;i--)
    {
        l[i] = min(l[i],l[i+1]-a[i]); //最重要的部分是这里
    }
 
    for(int i=0;i<m;i++)
    {
        for(int j = l[i];j<=l[i]+a[i]-1;j++)
        {
            ans[j] = i+1;
        }
//        cout << l[i]<<" "<<endl;
    }
    for(int i=1;i<=n;i++)
        cout << ans[i]<<" ";
    cout <<endl;
}





分界线

D. Binary String Minimizing

在这里插入图片描述

题意

	 最小化给出的二进制数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+100;
vector<int>pos;
int main()
{
    ll t , n , k;
    string s;
    cin >>t;
    while(t--)
    {
        pos.clear();
        cin >> n >> k;
        cin >> s;
        for(int i=0;i<n;i++)
        {
            if(s[i]=='0')pos.push_back(i);
        }
        int len = pos.size();
 
        for(int i=0;i<len;i++)
        {
            if(pos[i]-i<=k)
            {
                if(s[pos[i]]<s[i]){
                s[i] = '0';
                s[pos[i]] = '1';
                k = k - pos[i]+i;
                }
            }
            else if(pos[i]-i>k&&k)
            {
                s[pos[i]-k] = '0';
                s[pos[i]] = '1';
                k = 0;
            }
            else {break;}
        }
        cout << s <<endl;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值