[TopCoder]棍子
题目描述
你有一堆棍子。每个木棒的长度是一个正整数。
你想要一组棍子所有的棍子都有相同的长度。您可以通过执行零个或多个步骤来更改当前集合。每个步骤必须如下所示:
你选择一根棍子。所选棒的长度必须至少为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]棍子的更多相关文章
- TopCoder kawigiEdit插件配置
kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...
- 记第一次TopCoder, 练习SRM 583 div2 250
今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...
- TopCoder比赛总结表
TopCoder 250 500 ...
- Topcoder几例C++字符串应用
本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...
- TopCoder
在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...
- TopCoder SRM 596 DIV 1 250
body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...
- 将外卖O2O广告一棍子打成竞价排名,秤把平了吗?
近日,诸多媒体报道称美团外卖.饿了么等外卖O2O将竞价排名引入外卖平台当中进行广告运营一事闹得沸沸扬扬.那么,美团外卖.饿了么真的都是竞价排名吗? 其实,美团外卖的付费推广仅仅只是针对列表的固定位置, ...
- 求拓扑排序的数量,例题 topcoder srm 654 div2 500
周赛时遇到的一道比较有意思的题目: Problem Statement There are N rooms in Maki's new house. The rooms are number ...
- TopCoder SRM 590
第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement Fox Ciel is going to play Gomoku with her friend ...
随机推荐
- 【gdoi2018 day2】第二题 滑稽子图(subgraph)(性质DP+多项式)
题目大意 [gdoi2018 day2]第二题 滑稽子图(subgraph) 给你一颗树\(T\),以及一个常数\(K\),对于\(T\)的点集\(V\)的子集\(S\). 定义\(f(S)\)为点集 ...
- vue---由nextTick原理引出的js执行机制
最开始查看nextTick这个方法的时候,眼瞎看成了nextClick...我还在疑问难道是下一次click之后处理事件... 然后用这个方法的时候,就只知道是用在DOM更新之后调用回调方法. 这时就 ...
- 状态压缩动态规划 状压DP
总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...
- restful设计规范
什么是restful? REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度类 ...
- 微服务之服务中心—Eureka
Eureka 简介Eureka 是 Spring Cloud Netflix 的一个子模块,也是核心模块之一,用于云端服务发现,是一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故 ...
- 苹果手机iOS11中fixed弹出框中input光标错位问题
最近遇到了一个移动前端的BUG:手机弹出框中的输入框focus时光标可能会错位. 刚开始时我完全不知道错误原因是什么,在电脑上调试时完全没有问题,手机上出现问题时也没有找到规律.后来在网上搜索了大量的 ...
- DirectX11 With Windows SDK--22 立方体映射:静态天空盒的读取与实现
前言 这一章我们主要学习由6个纹理所构成的立方体映射,以及用它来实现一个静态天空盒. 但是在此之前先要消除两个误区: 认为这一章的天空盒就是简单的在一个超大立方体的六个面内部贴上天空盒纹理: 认为天空 ...
- How to learn PDE (怎么学偏微分方程)
To learn PDE, you need some knowledge of physics (to build up the intuition), solid training of anal ...
- Python DB operation
mysql http://www.cnblogs.com/zhangzhu/archive/2013/07/04/3172486.html 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目 ...
- LINUX常用操作快捷方式
1. tab 命令补全 这个按键地球人都知道了! 2. Esc+ . 补全最后一次键入的字符 3.Ctrl + a 跳到命令开头 4.Ctrl+e 跳到命令结尾 5 Ctrl+ u 光标处到命令行开 ...