【Codeforces Round #507 (Div. 2, based on Olympiad of Metropolises) B】Shashlik Cooking

【链接】 我是链接,点我呀:)
【题意】


在这里输入题意

【题解】


翻转一次最多影响2k+1个地方。
如果n<=k+1
那么放在1的位置就ok.因为能覆盖1..k+1
如果n<=2
k+1
那么就放在1+k的位置就ok.能覆盖1..2k+1
其他情况
考虑temp=n%(2
k+1)的值。
如果temp==0
那么美滋滋。直接操作n/(2k+1)次就ok,
分别在1+k,1+k+2
k+1,1+k+2k+1+2k+1....
刚好占据n个位置。
如果k+1<=temp<=2k
那么我们可以在temp-k的位置操作一次。
这样的话。一开始的位置我们就能先翻转temp个了。然后剩下的再按照2
k+1依次操作(就能刚好铺满n个了)
如果1<=temp<=k
那么我们考虑在1位置操作一次。
这样能翻转1..k+1这k+1个位置。
对于最后的2k+1和temp这两段。
我们把它分解一下。
因为已经翻转了k+1个
所以还剩下rest=2
k+1+temp-(k+1)
会发现rest∈[k+1,2*k]
而这么一段。
可以在n-(rest-k)+1的位置操作一次填掉。
那么剩下的部分就能被2k+1整除了。按顺序放就可以了。
然后这两种temp%(2
k+1)!=0的情况操作次数都是n/(2*k+1) + 1

【代码】

#include <bits/stdc++.h>
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define all(x) x.begin(),x.end()
#define pb push_back
#define lson l,mid,rt<<1
#define ri(x) scanf("%d",&x)
#define rl(x) scanf("%lld",&x)
#define rs(x) scanf("%s",x)
#define rson mid+1,r,rt<<1|1
using namespace std;

const double pi = acos(-1);
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};

const int N = 20;

int n,k;

int main(){
    #ifdef LOCAL_DEFINE
        freopen("rush_in.txt", "r", stdin);
    #endif
    scanf("%d%d",&n,&k);
    if (k+1>=n){
        cout<<1<<endl;
        cout<<1<<endl;
        return 0;
    }else if (2*k+1>=n){
        //n>k+1
        cout<<1<<endl;
        cout<<k+1<<endl;
        return 0;
    }
    int temp = n%(2*k+1);
    int points = n/(2*k+1);
    if (temp==0){
        printf("%d\n",points);
        int x = k+1;
        rep1(i,1,points){
            cout<<x<<' ';
            x = x+k+1+k;
        }
    }else {
        if (temp>=k+1){
            points++;
            cout<<points<<endl;
            int x = temp-k;
            rep1(i,1,points){
                cout<<x<<' ';
                x = x + k+1+k;
            }
        }else{
            //temp<=k
            points++;
            cout<<points<<endl;
            cout<<1<<' ';
            points--;

            int x = 1;
            rep1(i,1,points){
                x = x+k+1+k;
                cout<<x<<' ';
            }
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/9597328.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值