题目描述

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

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

你选择一根棍子。所选棒的长度必须至少为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. sublime text 批量删除空白行

    CTRL+H打开replace功能,勾选上左侧的regular expression,并填写 find what栏 : \s+$  (正则表达式)replace with栏 : (这行留空) 接着点r ...

  2. create table as 和create table like的区别

    create table as 和create table like的区别 对于MySQL的复制相同表结构方法,有create table as 和create table like 两种,区别是什么 ...

  3. [物理学与PDEs]第3章第4节 磁流体力学方程组的数学结构

    1.  在流体存在粘性.热传导及 $\sigma\neq \infty$ 时, 磁流体力学方程组是一个拟线性对称双曲 - 抛物耦合组. 2.  在流体存在粘性.热传导但 $\sigma=\infty$ ...

  4. INI配置文件的格式

    为什么要用INI文件?如果我们程序没有任何配置文件时,这样的程序对外是全封闭的,一旦程序需要修改一些参数必须要修改程序代码本身并重新编译,这样很不好,所以要用配置文件,让程序出厂后还能根据需要进行必要 ...

  5. Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值

    转载请标明出处:http://blog.csdn.net/donkor_/article/details/53487133 前言: 作为谷歌在2013年为开发者提供的IDE环境工具Android St ...

  6. 可变有序列表list

    list是一种有序的集合,可以随时添加和删除其中的元素. 声明方法 list名=[元素1,元素2,元素3,--] >>> name=['Tom','David','Tony'] &g ...

  7. Vue技术内幕 出去看看吧 榨干部分小细节

    vue\src\platforms\web\entry-runtime-with-compiler.js /** * Get outerHTML of elements, taking care * ...

  8. 预置app/apk到系统 && 预置so库进系统 && 预置普通文件和文件夹进系统

    https://blog.csdn.net/zhandoushi1982/article/details/4695460

  9. PHP 【四】

    数组 $string = array(x,y,z); <?php$cars=array("Volvo","BMW","Toyota") ...

  10. Struts2优缺点

    优点: (1)  实现了MVC模式,层次结构清晰,使程序员只需关注业务逻辑的实现. (2)  丰富的标签库,大大提高了开发的效率. (3) Struts2提供丰富的拦截器实现. (4) 通过配置文件, ...