CodeForces-1040B Shashlik Cooking(贪心)

题目大意:

n个节点,选择一个节点的时候翻转这个节点与两侧k个节点(够的话),求最少几次全部翻到反面。

ps:同一个节点翻两次会翻回正面。

思路:

贪心,尽量多的选能翻翻2k+1个节点的节点,即在中间尽量多的划分长度为2k+1的区间。为使中间节点数恰好为(2k+1)的整数倍,两侧特殊考虑。

在边上最少翻k+1块,最多2k+1,故两边留的总节点数d要满足 2k+1\leqslantd\leqslant4k+2

当2k+2\leqslantd\leqslant3k+2时,一侧取k+1的最小情况,一侧根据剩余节点选择;

当3k+2<d\leqslant4k+2时,一侧去2k+1的最大情况,一侧根据剩余节点选择。

若找不出这个范围内的d,直接输出中点即可

#include<bits/stdc++.h>
using namespace std;
vector<int> ans;
int main()
{
	int n,k; scanf("%d%d",&n,&k);
	int d = n%(2*k+1);
	int t = n/(2*k+1);
	while(d<=n){
		d+=2*k+1;
		if(d>=2*k+2&&d<=4*k+2) break;
	}
	if(d>=2*k+2&&d<=4*k+2&&d<=n){
		ans.clear();
		if(d<=3*k+2){
			int l = d - 2 * k - 1;
			while(l<=n){
				ans.push_back(l);
				l += 2 * k + 1;
			}
		}
		else{
			int l = d - 3 * k - 1;
			while(l<=n){
				ans.push_back(l);
				l += 2 * k + 1;
			}
		}
		printf("%d\n",ans.size());
		for(int i=0;i<ans.size();i++) printf("%d ",ans[i]);
		printf("\n");
	}
	else{
		printf("1\n%d\n",(n+1)/2);
	}
}
发布了28 篇原创文章 · 获赞 8 · 访问量 2811

猜你喜欢

转载自blog.csdn.net/IuSpet/article/details/83187573