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;
}