博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeForces - Duff and Weight Lifting - [I/O加速]
阅读量:5732 次
发布时间:2019-06-18

本文共 2388 字,大约阅读时间需要 7 分钟。

CodeForces - Duff and Weight Lifting - #326 (Div. 1)

c++ iostream I/O优化

一句话题意:有若干个数字,都是2的n次幂;每次取出若干个数字,且要保证取出的数字之和也是2的n次幂;问至少要取多少次。


样例输入:

5
1 1 2 3 3

样例输出:

2


解:

我们从最简单的样例入手。

样例输入可以整理如下。x的后面表示这个数字的出现次数。

2^1 x2

2^2 x1
2^3 x2

我们发现,两个相同幂次的数,刚好能“等价变换”为更高次的数。

2^1 x2 => 2^2 x1

再加上已有的2^2,总共有2个2^2啦。于是,继续变换,

2^2 x2 => 2^3 x1

再加上已有的2个2^3,就有3个2^3啦。

2^3 x2+1

取出其中两个进行“变换”,最终结果就是

2^3 x1

2^4 x1

然后,我们发现不管怎么操作都无法进一步组合两个数进行变换。现在有两个数,所以答案是2

做到这里,就不难看出其中的规律。二进制下的“进位”而已。

#include 
#include
#include
using namespace std;int orz[1000000+10000];int l[] ={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576};int search(int n){ for(int i = 0;i<20;i++){ if(l[i+1]>=n){ return i; } } return -1;}int main(){ std::ios::sync_with_stdio(false); std::cin.tie(0); int n,t; scanf("%d", &n); int step = 0; int max = 0; for(int i = 0;i
max?t:max); orz[t]++; } for(int i = 0;i<=max;i++){ if(orz[i] == 0) continue; int now_cnt = orz[i]; int pow; while(now_cnt){ if(now_cnt == 1) step++; now_cnt -= l[pow = log2(now_cnt)]; orz[max=(i+pow>max?i+pow:max),i+pow]++; } } printf("%d\n", step); return 0;}

其中两行,

std::ios::sync_with_stdio(false);  std::cin.tie(0);

就是所谓的iostream优化。

第一行的原理就是解除iostreamstdio的绑定。

第二行的原理是解除cincout的绑定。

详情请看。

为啥要优化呢?因为我起初做这题是用的51nod(这个网站提供这题的中文题目)的机器非常辣鸡,就是卡I/O。疯狂TLE。

我试了能AC的两种方法,第一种是删除所有c++特性语句,使用printfscanf,用c来提交;第二种就是所述的iostream优化。

题外话:

有些时候,自己重写printfscanf效率更高。

因为getcharputchar函数很快。

从qscqesze的上摘抄如下:

template
inline T& RD(T &x){ //cin >> x; //scanf("%d", &x); char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); '0' <= c && c <= '9'; c = getchar()) x = x * 10 + c - '0'; //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0'; return x; } int ____Case; template
inline void OT(const T &x){ //if (x == -1) printf("Case %d: NO\n", ++____Case); //else printf("Case %d: %d\n", ++____Case, x); //printf("%I64d\n", x); //printf("%.2lf\n", x); printf("%d\n", x); //cout << x << endl; }

这相当于重写了scanf

至于用putchar重写printf……以后再说吧,因为很少遇到大量输出的情况。

转载地址:http://xfmwx.baihongyu.com/

你可能感兴趣的文章
CentOS 7下安装部署Oracle11g图文教程
查看>>
#51CTO学院四周年# 相约烤鸭”
查看>>
python几个小用法
查看>>
初窥Quarts2D(二)
查看>>
XML
查看>>
Java 重写(Override)与重载(Overload)
查看>>
Vue+NodeJS+ElementUI 的简单示例
查看>>
php实现构建乘积数组(算法:替换)(语法错误:分号和$符号)
查看>>
php实现求一个数的质数因子
查看>>
laravel中建立公共视图的方法
查看>>
Selenium&PhantomJS 完成爬取网络代理
查看>>
Android测试环境搭建(win7)
查看>>
C#后台调用浏览器打开下载连接地址的三种方法
查看>>
PHP CURL抓取网页 simple_html_dom类
查看>>
【Heap-dijkstra】Gym - 100923B - Por Costel and the Algorithm
查看>>
git clone出现fatal: unable to access 'https://': SSL certificate problem: self signed certificate
查看>>
用MySQL创建数据库和数据库表
查看>>
计算题:挣值、预测、沟通、盈亏平衡点、
查看>>
RAM 大全-DRAM, SRAM, SDRAM的关系与区别
查看>>
Dedecms V5.7后台的两处getshell
查看>>