Codeforces Round #507 B. Shashlik Cooking

这道题,真香。

(话说shashlik好像是毛子们/东欧地区人民热爱的,一种类似于烤串的美食,wiki上的图片看起来很香的样子)

1477449-20180906085052957-216878126.jpg

嗯大概就是这个。

题目大意:

Miroslav正在烤串。

众所周知烤串是要翻动的。

有n个烤串,每个串一开始都是正面朝上的。对于某个烤串进行翻动操作,会使这个串以及相邻左右k个串都被翻动。

翻动会使正面朝上的串翻到反面,反面朝上的串翻到正面。

求最少翻动几次能够将n个串全部翻到反面。

输出最少翻动次数,以及翻动哪些串。

程式化的描述:

给定一个初始为0的数组,每次对 $ i $ 操作会使 $ [i-k,i+k] $ 之间的所有数字取反(0->1,1->0),最少操作多少次能够将整个数组变为1。

输出最少操作次数,以及操作数组的哪些元素。

题解:

首先是求最小操作次数。不难发现,每个串 $ i $ 都控制着 $ [i-k,i+k] $ 的区域。也就是说,每个串控制长度为 $ k*2+1 $ 的区域。

我们从1开始,枚举使用多少个长度为 $ k*2+1 $ 的区域,能把 $ n $ 覆盖掉。

$ ans $ 为需要翻转的烤串数量(最少翻动次数)。

int ans=0;
while(ans*(2*k+1)<n)ans++;
printf("%d\n",ans);

然后是求这些烤串的位置。

先求最左边的烤串的位置 $ l $ ,从1到 $ k+1 $ 枚举,因为每个烤串之间距离是已知的 $ (2k) $ ,所以可以算出最右边的烤串位置为 $ l+(ans-1)((2*k)+1) $

如果最右边的位置+k大于等于n,就可以了。


int l=1;
for(;l<=k+1 and (l+(ans-1)*((2*k)+1)+k)<n;l++){}

最后从 $ l $ 开始,下一个串的位置等于上一个的位置+ $ (2*k)+1 $ ,逐个输出就好了。


printf("%d ",l);
while(l+k<n){
    l=l+(2*k)+1;
    printf("%d ",l);
}

转载于:https://www.cnblogs.com/soul-M/p/9596160.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值