Codeforce - 1040B - Shashlik Cooking(思维)

版权声明:Andy https://blog.csdn.net/Alibaba_lhl/article/details/82491647

Input

7 2

Output

2
1 6

Input

5 1

Output

2
1 4

Source::Click here

题意

给你n串羊肉串,它们的编号依次为1,2,3,,,n。羊肉串初始状态全为正面,你的任务是将所有的羊肉串翻转过来。规则是:当每次选择一个位置pos进行翻转,pos-k和pos+k的位置都会被翻转。求最少多少次能将所有的羊肉串全部翻转过来。、

思路

这个题可以分类讨论。对n和2k+1的关系进行讨论。

  1. 当n<=2k+1,进行一次就可完成。因为选择一个pos,最大的覆盖范围是2k+1.
  2. 当n>2k+1,需要对r(r=n%(2k+1))进行讨论 ①:当r<k+1时,初始位置从1开始,每隔2k+1选定一个。原因:当余数为r<k+1时,可将序列表示为:k+1 2k+1 2k+1 2k+1 ,,, 2k+1 X (最后一组用X表示 k+1<=X<=2k,即可选择一个pos,不然会出现对同一个执行两次) ②:当r>=k+1时,初始位置从k+1开始,每隔2k+1选定一个。

                                                                                                                                                                                            

AC Code

#include<bits/stdc++.h>
using namespace std;

int n, k, r, idx;
vector<int> V;
int main()
{
    scanf("%d%d",&n,&k);
    r = n % (2 * k + 1);
    if(r == 0) r += (2 * k + 1);///当n是2k+1的整数倍,将余数记为2k+1用于后续操作
    if(n <= 2 * k + 1)///当n小于2k+1时,即即一次就能完成操作,如(左边k个,1,右边k个,即可以进行一次就能完成操作)
    {
        puts("1");
        printf("%d\n",min(n, k + 1));///若1+k<n,则应输出n
        return 0;
    }
    else if(r < k + 1) idx = 1;///当n大于2k+1且余数小于k+1,为了避免出现对同一个操作两次的情况出现,起始位从1开始
    else idx = k + 1;///当n大于2k+1且余数大于等于k+1,
    for( ; idx <= n; idx += (2 * k + 1)) V.push_back(idx);///将选定的序号(每隔2k+1)存入vecotr中
    int len = V.size();
    printf("%d\n",len);
    for(int i=0; i<len; i++)
    {
        if(i==0) printf("%d",V[i]);
        else printf(" %d",V[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Alibaba_lhl/article/details/82491647
今日推荐