1. 程式人生 > >CodeForces-1040B Shashlik Cooking(貪心)

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