题目描述

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

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

你选择一根棍子。所选棒的长度必须至少为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. (链表) lintcode 219. Insert Node in Sorted Linked List

    Description   Insert a node in a sorted linked list.   Example Example 1: Input: head = 1->4-> ...

  2. git && gitlab 使用

    安装略过 使用 基于公钥的认证登录,方便对用户进行权限控制 useradd -s /usr/bin/git-shell testgit #创建一个用户 或者直接useradd testgit 然后去/ ...

  3. EF CodeFirst系列(6)---配置1对1,1对多,多对多关系

    这一节介绍EF CodeFirst模式中的1对0/1,1对多,多对多关系的配置,只有梳理清楚实体间的关系,才能进行愉快的开发,因此这节虽然很简单但是还是记录了一下. 1. 1对0/1关系配置 1. 通 ...

  4. springBoot总结

    springBoot总结: ssm基本的依赖: <dependencies> <!--添加依赖thymeleaf 可以访问html页面--> <!--<depend ...

  5. [物理学与PDEs]第4章第3节 一维反应流体力学方程组 3.3 一维反应流体力学方程组的数学结构

    一维理想反应流体力学方程组是一阶拟线性双曲组.

  6. on duplicate key update简单使用

    1.最近在做项目的时候,遇到这样的一个问题,就是我每做完一件事情,都要更新一下统计表,然而要更新统计表,就要根据主键去统计表里面去查询是否已经有这样的一条记录,如果有那么就更新,如果没有那么就插入一条 ...

  7. MySQL学习7 - 外键的变种 三种关系

    一 介绍 二 如何找两张表之间的关系 三 表的三种关系 1.书和出版社 2.作者和书籍的关系 3.用户和博客 本节的重点 如何找出两张表之间的关系 表的三种关系 一 介绍 因为有foreign key ...

  8. uploadPreview上传图片前预览图片

    uploadPreview.js是一款图片上传前的预览插件.谷歌.火狐.IE都可以兼容,但是不支持safari. 相关的html代码: <!DOCTYPE html PUBLIC "- ...

  9. django项目实现中文检索

    在settings.py中设置 EMAIL_USE_SSL = True EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com EMAIL_POR ...

  10. mongoDB3.0版本使用express读取数据

    使用express连接数据库操作 var express = require('express'); var app = express(); var MongoClient = require('m ...