Amr and Chemistry---cf558C(暴力,加技巧)
2016-01-27 10:26
344 查看
题目链接:http://codeforces.com/problemset/problem/558/C
题意:有n个数,每个数都可以进行两个操作 *2 或者 /2,求最小的操作次数和,使得所有的数都相等;
计算一下时间复杂度可以知道每个数所能达到数的时间复杂度是log(1e5)最终的时间复杂度也就是 nlog(1e5), 所以暴力能过,
刚开始看到的时候一看数据范围就根本不敢暴力了。。。
我们可以把每个数所有变化情况都记录下来,并记录出现的次数,因为只有用1
View Code
题意:有n个数,每个数都可以进行两个操作 *2 或者 /2,求最小的操作次数和,使得所有的数都相等;
计算一下时间复杂度可以知道每个数所能达到数的时间复杂度是log(1e5)最终的时间复杂度也就是 nlog(1e5), 所以暴力能过,
刚开始看到的时候一看数据范围就根本不敢暴力了。。。
我们可以把每个数所有变化情况都记录下来,并记录出现的次数,因为只有用1
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #define N 100100 #define INF 0x3f3f3f3f #define met(a, b) memset(a, b, sizeof(a)) using namespace std; int num , cnt ; void F(int x) { int step = 0, t = x; cnt[x] ++; while(t*2 < N)///往上*2得到的都是偶数,直接记录; { t = t*2; step ++; num[t] += step; cnt[t] ++; } t = x, step = 0; while(t > 1) { if(t!=1 && t%2==1)///往下/2得到的可能是奇数, 如果是奇数的话继续往上*2; { int y = t/2; int step0 = step+1; while(y*2 < N) { y = y*2; step0 ++; num[y] += step0; cnt[y] ++; } } t = t/2; step ++; num[t] += step; cnt[t] ++; } } int main() { int n, x; while(scanf("%d", &n)!=EOF) { met(cnt, 0); met(num, 0); for(int i=0; i<n; i++) { scanf("%d", &x); F( x ); } int ans = INF; for(int i=0; i<N; i++) { if(n == cnt[i]) ans = min(ans, num[i]); } printf("%d\n", ans); } return 0; }
View Code
相关文章推荐
- Source Multiplayer Networking【转】
- java内存分配问题详解
- Android WebView使用经验总结
- input 全新属性
- 超图对接伟景航osg数据使用说明
- iOS 插件开发
- Linux系统中的异常堆栈跟踪简单实现
- 生成android证书
- 【Java多线程】之二:synchronized详解
- Houdini Pyro流体的插值变速
- 【摘】linux中fstab解说
- 查找数据库中某一列名
- 八一八可重用工作流(权当学习记录)
- jQuery Easyui学习之datagrid 动态添加、移除editor
- Linux 下 C++ 异常处理技巧
- 引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常 解决办法
- JavaEE web.xml 中ContextLoaderListener的解析
- 有用的学习网站链接
- hdu 4143(分解质因数)
- 使用组合模式与迭代器模式遍历文件夹中所有文件