CodeForces - 1040B Shashlik Cooking (贪心 + 细节)

Shashlik Cooking

Long story short, shashlik is Miroslav's favorite food. Shashlik is prepared on several skewers simultaneously. There are two states for each skewer: initial and turned over.

This time Miroslav laid out n skewers parallel to each other, and enumerated them with consecutive integers from 1 to n in order from left to right. For better cooking, he puts them quite close to each other, so when he turns skewer number i, it leads to turning k closest skewers from each side of the skewer i, that is, skewers number i−k, i−k+1, ..., i−1, i+1, ..., i+k−1, i+k (if they exist).

For example, let n=6 and k=1. When Miroslav turns skewer number 3, then skewers with numbers 2, 3, and 4 will come up turned over. If after that he turns skewer number 1, then skewers number 1, 3, and 4 will be turned over, while skewer number 2 will be in the initial position (because it is turned again).

As we said before, the art of cooking requires perfect timing, so Miroslav wants to turn over all n skewers with the minimal possible number of actions. For example, for the above example n=6 and k=1, two turnings are sufficient: he can turn over skewers number 2 and 5.

Help Miroslav turn over all nn skewers.

Input

The first line contains two integers nn and kk (1≤n≤1000, 0≤k≤1000) — the number of skewers and the number of skewers from each side that are turned in one step.

Output

The first line should contain integer l — the minimum number of actions needed by Miroslav to turn over all n skewers. After than print l integers from 1 to n denoting the number of the skewer that is to be turned over at the corresponding step.

Examples

Input

7 2

Output

2
1 6 

Input

5 1

Output

2
1 4 

Note

In the first example the first operation turns over skewers 1, 2 and 3, the second operation turns over skewers 4, 5, 6 and 7.

In the second example it is also correct to turn over skewers 2 and 5, but turning skewers 2 and 4, or 1 and 5 are incorrect solutions because the skewer 3 is in the initial state after these operations.

题意:对于一个串 i , 如果反转 i ,那么串 i - k 到 i + k 的所有串都将反转(如果存在), 问最后要是所有串都处于反转状态,最少需要反转那些串。

贪心策略:从1 , 和 n 开始反转,当最后剩下的串少于 2 * k + 1 的时候,可直接 将原来反转的串 向左 或 向右移动 (因为起始反转串为 1 和 n , 串 1 和 串 n 还有一部分是反转可用的)。      !!!!!  不过这只是对于 k != 0 且  k < n / 2 的情况  !!!!!

如果打算自己不看测试数据写,建议在 比较有状态的时候写。。。 菜鸡都看  测试数据 。QAQ, 比如

AC 代码:

#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)

using namespace std;

const int maxn = 1100;          /// 坑 巨多
int vis[maxn];                  /// 需要注意很多情况

int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k)){
        if(k == 0){             /// 特判
            printf("%d\n",n);
            for(int i = 1;i <= n;i ++) printf("%d ",i); printf("\n");
            continue;
        }
        else if(k >= n / 2){   /// 特判
            printf("1\n%d\n",(n + 1) / 2);      /// 当 n = 1 时,简单的输出 n / 2,就错了
            continue;
        }
        memset(vis,0,sizeof(vis));
        int l = 1,r = n;
        int coun = 1;
        while(r - l + 1 >= 2 * k + 1){
            if(coun == 1){
                for(int i = 1;i <= l + k;i ++)
                    if(i != l) vis[i] = 1;
                l = k + 2;
                for(int i = n;i >= r - k;i --)
                    if(i != r) vis[i] = 1;
                r = n - k - 1;
            }
            else {
                for(int i = l;i <= l + 2 * k + 1;i ++)
                    if(i != l + k) vis[i] = 1;
                l = l + 2 * k + 1;
                if(r - l + 1 < 2 * k + 1) break;
                for(int i = r;i >= r - 2 * k - 1;i --)
                    if(i != r - k) vis[i] = 1;
                r = r - 2 * k - 1;
            }
            ++ coun;
        }

//        printf("%d %d\n",l,r);
//        for(int i = 1;i <= n;i ++)
//            printf("%d ",vis[i]); printf("\n");

        if(l > r){ l = n / 2; r = n / 2 - 1; }

        int a[maxn] ={0}, p = 0;
        int copa[maxn] = {0}, copp = 0;
        for(int i = 1;i < l;i ++)
            if(!vis[i]) a[++ p] = i;
        for(int i = r + 1;i <= n;i ++)
            if(!vis[i]) copa[++ copp] = i;

        printf("%d\n",p + copp);
        int x = r >= l ? (r - l + 1) : 0;

        if(x % 2 == 1){
            for(int i = 1;i <= p;i ++)
                printf("%d ",a[i] + x / 2 + 1);
        }
        else {
            for(int i = 1;i <= p;i ++)
                printf("%d ",a[i] + x / 2);
        }

        for(int i = 1;i <= copp;i ++)
            printf("%d ",copa[i] - x / 2);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/no_O_ac/article/details/82740888
今日推荐