zoukankan      html  css  js  c++  java
  • Codeforces Round #507 B. Shashlik Cooking

    这道题,真香。

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

    嗯大概就是这个。

    题目大意:

    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
    ",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);
    }
    
    
  • 相关阅读:
    linux之iptable案例
    nginx常用命令参数
    laravel中的多对多关系详解
    MySql计算时间差函数
    总结下Mysql分表分库的策略及应用
    swoole扩展实现真正的数据库连接池
    linux常用命令整理
    innodb mvcc实现机制
    mysqlslap 压力测试使用总结
    mysql索引总结
  • 原文地址:https://www.cnblogs.com/soul-M/p/9596160.html
Copyright © 2011-2022 走看看