HDU 7066 - NJU emulator(构造题)
提供一种不同于官方题解、需要的操作次数比官方题解多(官方题解大概是 \(2\times 16\),我这大概是 \(3\times 16\)),但能通过此题的做法。
首先我们考虑一个暴力,我们设一个阈值 \(B=2^k\),然后我们考虑预处理出 \(1\sim B\) 中所有数,即,先一遍 p1,然后每次 dup 一遍,然后调用 add 指令给栈顶上的数加 \(1\)(显然此时 \(1\) 在栈中),如此操作 \(B-1\) 次即可让 \(1\sim B\) 中所有数都在栈中。然后再新开一个元素表示答案,然后我们就每 \(k\) 个元素一块,从高位开始,每次乘以 \(2^k\)(由于 \(2^k\) 此时已经在栈中,直接调用 mul 指令即可),然后取出这 \(k\) 位表示的数,调用 add 指令累加到答案中即可,不难发现这样操作次数为 \(2(B+\dfrac{64}{k})\) 级别的,取 \(k=4\) 即 \(B=16\) 时最优。
但这样需要 \(4\times 16\) 次操作,无法卡过本题 \(50\) 次的限制,考虑优化,注意到本题还有一个 sub 命令我们没有调用,因此我们考虑这样一件事情,我们第一部分只预处理出 \(1\sim 8\) 附加上 \(16\),这样我们第二部分时,假设我们目前处理的这 \(k\) 位值为 \(v\),那么如果 \(v\le 7\),显然 \(v\) 此时已经在栈中,我们就直接用 add 命令将 \(v\) 加到栈顶元素上去即可,但如果 \(v\ge 8\) 就不太好直接处理了。一个很直观的想法是,我们直接加 \(16\),然后减掉该减的部分,但这样还是会卡成 \(4\times 16\),样例 \(N=2^{64}-1=18446744073709551615\) 都过不了,不过注意到在上一步中我们已经乘了个 \(16\),因此我们考虑在上一轮操作中“预测未来”,即,如果下一轮表示的数 \(\ge 8\) 那么我们就让这轮中最后四位表示的数变成 \(v+1\),否则直接调到 \(v\) 即可,这样就省去了那个 \(+16\) 的操作了。这样操作次数就是 \(3\times 16\) 级别的了。
还有一些地方需要卡卡,否则可能会出现 \(51\) 次操作的悲催情况。
u1s1 这题操作次数卡得是真的紧,下面这份代码中操作次数的上限就是 \(50\),在 \(n=2^{63}-1\) 处取到:
void solve(){
u64 x;scanf("%llu",&x);
printf("p1\n");
for(int i=2;i<=8;i++){
printf("dup\n");
printf("add %d\n",i-1);
} printf("dup\nadd 1\n");
int need=(x>>60&15)+((x>>56&15)>=8);
if(!need) printf("p1\nsub 9\n");
else if(need==1) printf("p1\n");
else if(1<need&&need<=9){
printf("p1\nadd %d\n",11-need);
} else if(need>9){
printf("dup\n");
if(need!=16) printf("sub %d\n",10-(16-need));
} printf("mul 1\n");
for(int i=14;~i;i--){
int v1=(x>>(i<<2)&15),v2=(!i)?0:(x>>(i-1<<2)&15);
if(v1<8&&v2<8){
if(v1) printf("add %d\n",10-v1);
} else if(v1<8&&v2>=8){
printf("add %d\n",9-v1);
} else if(v1>=8&&v2<8){
printf("sub %d\n",10-(16-v1));
} else {
if(v1^15) printf("sub %d\n",11-(16-v1));
} if(i) printf("mul 1\n");
} printf("end\n");
}
int main(){
int qu;scanf("%d",&qu);
while(qu--) solve();
return 0;
}
/*
7
15
16
16843009
1061109567
1152921504606846975
1152921504606846976
2305843009213693951
*/
HDU 7066 - NJU emulator(构造题)的更多相关文章
- HDU 5355 Cake (WA后AC代码,具体解析,构造题)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5355 题面: Cake Time Limit: 2000/1000 MS (Java/Others) ...
- hdu4671 Backup Plan ——构造题
link:http://acm.hdu.edu.cn/showproblem.php?pid=4671 其实是不难的那种构造题,先排第一列,第二列从后往前选. #include <iostrea ...
- HDU 5573 Binary Tree 构造
Binary Tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5573 Description The Old Frog King lives ...
- cf251.2.C (构造题的技巧)
C. Devu and Partitioning of the Array time limit per test 1 second memory limit per test 256 megabyt ...
- Educational Codeforces Round 7 D. Optimal Number Permutation 构造题
D. Optimal Number Permutation 题目连接: http://www.codeforces.com/contest/622/problem/D Description You ...
- HDU 5710 Digit-Sum (构造)
题意: 定义S(N) 为数字N每个位上数字的和.在给两个数a,b,求最小的正整数n,使得 a×S(n)=b×S(2n). 官方题解: 这道题目的结果可能非常大,所以我们直接枚举n是要GG的. 首先可以 ...
- Codeforces 482 - Diverse Permutation 构造题
这是一道蛮基础的构造题. - k +(k - 1) -(k - 2) 1 + k , 1 , k , 2, ....... ...
- BZOJ 3097: Hash Killer I【构造题,思维题】
3097: Hash Killer I Time Limit: 5 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 963 Solved: 36 ...
- HDU.5385.The path(构造)
题目链接 最短路构造题三连:这道题,HDU4903,SRM590 Fox And City. \(Description\) 给定一张\(n\)个点\(m\)条边的有向图,每条边的边权在\([1,n] ...
随机推荐
- spark 解决错误java.io.InvalidClassException
今天遇到一个现场问题,任务报错java.io.InvalidClassException.在开发环境是没有报错的,正式环境报错.大概类似于下面这样(非报错原文,摘自网上同类博客) java.io.In ...
- noj -> 跳马
00 题目 描述: 在国际象棋中,马的走法与中车象棋类似,即俗话说的"马走日",下图所示即国际象棋中马(K)在一步能到达的格子(其中黑色的格子是能到达的位置). 现有一200*20 ...
- 剑指offer:JZ8 二叉树的下一个结点
JZ8 二叉树的下一个结点 描述 给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针.下图为一棵有9个节点的二叉 ...
- 莱特币(LTC)开发环境搭建
Linux系统下搭建莱特币LTC开发环境 1.简介 2.LTC 客户端下载 3.解压到一个固定的目录中 4.启动客户端 4.1.参数解释: 4.2.更多详细的配置 5.执行命令测试一下 6.获取莱特币 ...
- Noip模拟32(再度翻车) 2021.8.7
T1 Smooth 很水的一道题...可是最傻 的是考场上居然没有想到用优先队列优化... 上来开题看到这个,最一开始想,这题能用模拟短除法,再一想太慢了,就想着优化 偏偏想到线性筛然后试别的素 ...
- stm32f103中断学习总结
一.NVIC 介绍 NVIC 英文全称是 Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于 M3 内核的一个外设,控制着芯片的中断相关功 ...
- python pip whl安装和使用
转载:https://www.cnblogs.com/klb561/p/9271322.html 1 python的安装 首先,从python的官方网站 www.python.org下载需要的pyth ...
- 栈的压入、弹出顺序 牛客网 剑指Offer
栈的压入.弹出顺序 牛客网 剑指Offer 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是 ...
- 重学STM32---(十)之CAN通信(二)
目录 前言 程序编写 主代码 测试 前言 CAN协议是非常难的,但是在stm32中却是简单的,只需要我们配置寄存器即可,,,即使这样,我在学习的时候也遇到了许多困难 程序编写 1.开时钟,不用说 ...
- oracle 数据库修改端口号1521
1.关闭监听 2.修改配置文件,port=1933 #vi $ORACLE_HOME/network/admin/listener.ora 3.登录并查看local_listener参数,因为使用的是 ...