题目描述

你有一堆棍子。每个木棒的长度是一个正整数。

你想要一组棍子所有的棍子都有相同的长度。您可以通过执行零个或多个步骤来更改当前集合。每个步骤必须如下所示:

你选择一根棍子。所选棒的长度必须至少为2。设L为所选木棍的长度。

如果L是偶数,把棍子切成两根长度为L/2的棍子。否则,把它切成长度为(L-1)/2和(L+1)/2的棒。把两根新棍子中的一根留下,把另一根扔掉。

可以证明,任何一种集合都可以变成一种长度相同的集合。给定当前棍子集合的长度,计算并返回达到目标所需的最小步骤数。

输入

多组数据,第一行一个整数T,表示数据组数,T<=6

每组数据:

第一行一个整数N,表示棍子数目。(2<=N<=50)

第二行N个整数,a[i]表示第i个棍子的长度。(1<=a[i]<=10^9)

输出

输出达到目标所需的最小步骤数

样例输入

4
2
11 4
4
1000 1000 1000 1000
7
1 2 3 4 5 6 7
6
13 13 7 11 13 11

样例输出

3
0
10
11

Solution

这道题需要注意的是当棍子长度是奇数的时候情况是不唯一的;

这样如果存储所有可能的状态是 \(2^30\) 级别的, 显然不能承受.

但是我们发现一个 性质 : 对于一个长度是奇数的棍子, 执行 k 次操作的可能长度只有 2 种, 这是因为当一个奇数被分成 奇数+偶数 时, 偶数接下来的所有情况都会被包含在奇数里. 所以偶数往下延伸的情况是没有必要的,每一层只有 1 个节点会往后延伸, 每一层最多只有 2 个节点.

这有点像线段树的性质.

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
 
int n, step[55][31][2], maxstep[55];
 
inline int solve(int len){
    int ans = 0;
    for (int i = 1; i <= n; ++i){
        bool check = false;
        for (int j = 0; j <= 30; ++j)
            if (step[i][j][0] == len || step[i][j][1] == len){
                ans += j;
                check = true;
                break;
            }
        if (!check) return 100000000;
    }
    return ans;
}
 
int main(){
    int T; scanf("%d", &T);
    while (T--){
        scanf("%d", &n); memset(step, 0, sizeof(step));
        for (int i = 1; i <= n; ++i){
            scanf("%d", &step[i][0][0]);
            maxstep[i] = 0; int x = step[i][0][0];
            while (x > 1){
                ++maxstep[i];
                if (x % 2 == 0) step[i][maxstep[i]][0] = x / 2, x = x / 2;
                else{
                    step[i][maxstep[i]][0] = (x-1) / 2;
                    step[i][maxstep[i]][1] = (x+1) / 2;
                    if (x % 4 == 1) x = (x+1) / 2;
                    else x = (x-1) / 2;
                }
            }
        }
 
        /*for (int i = 1; i <= n; ++i)
            for (int j = 0; j <= maxstep[i]; ++j)
                printf("(%d,%d)%c", step[i][j][0], step[i][j][1], (j < maxstep[i]) ? ' ' : '\n');*/
         
        int Ans = 100000000;
 
        for (int i = 0; i <= maxstep[1]; ++i){
            for (int j = 0; j <= 1; ++j)
                if (step[1][i][j]){
                    Ans = min(Ans, solve(step[1][i][j]));
                }
        }
 
        printf("%d\n", Ans);
    }
    return 0;
}

[TopCoder]棍子的更多相关文章

  1. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  2. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  3. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  4. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  5. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

  6. TopCoder SRM 596 DIV 1 250

    body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...

  7. 将外卖O2O广告一棍子打成竞价排名,秤把平了吗?

    近日,诸多媒体报道称美团外卖.饿了么等外卖O2O将竞价排名引入外卖平台当中进行广告运营一事闹得沸沸扬扬.那么,美团外卖.饿了么真的都是竞价排名吗? 其实,美团外卖的付费推广仅仅只是针对列表的固定位置, ...

  8. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  9. TopCoder SRM 590

     第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement     Fox Ciel is going to play Gomoku with her friend ...

随机推荐

  1. 转:centos 7 安装音频视频解码器

    (原文:https://blog.csdn.net/zhou1519/article/details/39035233/) 1.安装额外的软件源epel和nux-dextop rpm -Uvh htt ...

  2. python集合(set)的运算

    1.交集 In [1]: a = {1,2,3,4} In [2]: b = {3,4,5,6} In [3]: a & b Out[3]: {3, 4} In [4]: a.intersec ...

  3. C#设计模式(16)——中介者模式

    1.中介者模式介绍 中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系,中介者使各个对象之间不需要显式地相互引用,从而降低耦合性.在开发中我们会遇到各个对象相互引用的情况,每个对象都可以和多 ...

  4. 如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件

    如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件 最近初学Git,而且在使用的IDE是IntelliJ IDEA,发现IDEA在提交项目到本地仓库的时候,会把.idea文件 ...

  5. 第六节:框架搭建之EF的Fluent Api模式的使用流程

    一. 前言 沉寂了约一个月的时间,今天用一篇简单的文章重新回归博客,主要来探讨一下Fluent Api模式在实际项目中的使用流程. 1. Fluent API属于EF CodeFirst模式的一种,E ...

  6. SpringBoot系列: Spring项目异常处理最佳实践

    ===================================自定义异常类===================================稍具规模的项目, 一般都要自定义一组异常类, 这 ...

  7. [物理学与PDEs]第4章习题4 一维理想反应流体力学方程组的守恒律形式及其 R.H. 条件

    写出在忽略粘性与热传导性, 即设 $\mu=\mu'=\kappa=0$ 的情况, 在 Euler 坐标系下具守恒律形式的一维反应流动力学方程组. 由此求出在解的强间断线上应满足的 R.H. 条件 ( ...

  8. 利用div绘制细线居中

    利用div配合css代码实现细线方式: 块级元素水平居中步骤: 设置宽度width 设置margin-left:auto; 设置margin-right:auto; 实现方法是,让其左右两边的外边距自 ...

  9. 6.linux安装tomcat

    1.下载安装包 https://tomcat.apache.org/download-80.cgi       2.用 WinSCP 将本地的安装包 上传到 linux 服务器中   3.解压安装包( ...

  10. Vue生命周期中mounted和created的区别

    参考链接:https://blog.csdn.net/xdnloveme/article/details/78035065