CodeForces 1040B(思维题)
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 nn skewers parallel to each other, and enumerated them with consecutive integers from 11 to nn in order from left to right. For better cooking, he puts them quite close to each other, so when he turns skewer number ii, it leads to turning kk closest skewers from each side of the skewer ii, that is, skewers number i−ki−k, i−k+1i−k+1, ..., i−1i−1, i+1i+1, ..., i+k−1i+k−1, i+ki+k (if they exist).
For example, let n=6n=6 and k=1k=1. When Miroslav turns skewer number 33, then skewers with numbers 22, 33, and 44 will come up turned over. If after that he turns skewer number 11, then skewers number 11, 33, and 44 will be turned over, while skewer number 22will 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 nn skewers with the minimal possible number of actions. For example, for the above example n=6n=6 and k=1k=1, two turnings are sufficient: he can turn over skewers number 22 and 55.
Help Miroslav turn over all nn skewers.
Input
The first line contains two integers nn and kk (1≤n≤10001≤n≤1000, 0≤k≤10000≤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 ll — the minimum number of actions needed by Miroslav to turn over all nn skewers. After than print ll integers from 11 to nndenoting the number of the skewer that is to be turned over at the corresponding step.
Examples
7 2
2
1 6
5 1
2
1 4
Note
In the first example the first operation turns over skewers 11, 22 and 33, the second operation turns over skewers 44, 55, 66 and 77.
In the second example it is also correct to turn over skewers 22 and 55, but turning skewers 22 and 44, or 11 and 55 are incorrect solutions because the skewer 33 is in the initial state after these operations.
一开始没看清题意,wa了几次,看懂了题以后,就好做了。
题意:给你一排饼,用数字1~n表示他们的代号。每次给你两个数字,第一个数字表示饼的数目(即n),第二个数字(即m)表示假设选择翻起的饼是代号为a的话,那么代号为[a-m,a+m]的饼都会跟着被翻起。
然后题目要你求的是:把那些饼全翻起来最少的次数,然后输出那个次数和每一次翻起的位置。。
思路:这题给出的数据不大,所以不用什么算法,直接暴力了。我的思路是:假设每次给出的两个数字是n和m,翻一次可以翻起的最多的饼的数目为2m+1,所以就计算一个n%(2*m+1),如果n%(2*m+1)等于0,那就一个循环输出答案就好了,如果n%(2*m+1)!=0,那就把n%(2*m+1)和m+1比一下(因为比m+1小的话,会翻起前面翻过的),若是比m+1大的话,最后翻的那个为n%(2*m+1)的一半那个,比m+1更小的话,就向前查找。然后再依次输出答案就可以了。
注意:要注意m等于0的情况(被这个害苦了)。
代码:#include<stdio.h> #include<string.h> int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n<=2*m+1)//判断是否小于2*m+1,若小于直接输出n/2+1 { int a=1; printf("%d\n",a); printf("%d\n",n/2+1); continue; } else if(m==0)//考虑m等于0的情况 { printf("%d\n",n); for(int i=1;i<=n;i++) printf("%d ",i);//若m等于0直接循环输出 continue; } else { int a=n%(2*m+1); int b=n/(2*m+1); int d=m+1; if(a==0) { printf("%d\n",b); for(int i=1;i<=b;i++) { printf("%d ",d);//若a==0循环输出d d+=2*m+1; } } else if(a<m+1&&a!=0) { for(int i=1;i<=m+1;i++)//向前找 { d--; a++;//更新a的值 if(a==m+1)//a==m+1的时候就满足翻最后一次的时候不会把前面翻过了的反过来 break; } printf("%d\n",b+1); for(int i=1;i<=b;i++) { printf("%d ",d);//循环输出 d+=2*m+1; } printf("%d\n",n); } else//a>=m+1的情况 { printf("%d\n",b+1); for(int i=1;i<=b;i++) { printf("%d ",d); d+=2*m+1; } printf("%d\n",b*(2*m+1)+m+1);//保证不会把前面翻过了的翻过来 } } } return 0; }
学无止境,自己还是个菜鸡。努力吧,少年!