分类讨论大法好!

$ solution: $

先说一下我对这个题目的态度:

首先这一题是贪心,这个十分明显,看了一眼其他题解都是十分优秀的贪心,可是大家都没有想过吗:你们贪心都是在区间 $ [l,r] $ 上枚举的贪心,虽然每一次可以直接加上 10 的阶乘,但你们毕竟是用的 $ int $ , $ long long $  啊!。这一题得正解复杂度是 $ log_{10}(n) $ 的,不得不说题目的数据范围给的太小了只有 $ 10^9 $ ,如果按照复杂度,数据范围甚至可以到 $ 10^{10000000} $ 级别,这个时候你们难道还能在区间 $ [l,r] $ 上枚举吗?(高精怕都要超时!)

所以虽然分类讨论十分麻烦,甚至代码很长,但它才应该是真正意义上的正解啊!(当然,考场见机行事)

好的,不做“推销”了,我们进入正文。

首先这一题,我们可以用字符串的方式读入两个端点值。然后如果我们仔细读题,就可以发现一些贪心方案

  1. 我们要让最终的价格数的高位上不是0的数尽可能的少!(当然,要在末尾全是0的基础上)
  2. 只有当不是0的数确定下来,我们再来判断最后一个不是0的数能否为5!
  3. 如果最后一个不是0的数不能为5,我们就要让最后一个不是0的数尽可能的小!
  4. 让最终得到的价格数尽可能的小!

开始讨论之前先让你们有个思维准备:先看看下面代码有多少个 $ continue $ ,我们大概就要讲多少种情况。首先我们准备一个快写函数:将字符串 $ s $ 前 $ j-1 $ 位输出,然后将第 $ j $ 为换成字符 $ k $ ,再输出 $ n $ 个0

然后为了涵盖多种情况,我们发现如果两个数的长度不一样,是很难讨论的。于是我们分三种情况:(两个数长度差了2位或以上)(两个数的长度差为1)(两个数长度相同)

两个数长度差了2位或以上:(这个想一下,我们发现只有两种情况

  1. 如果较小的数的最高位比5小,就换成5输出(要特判5,50,500,5000......)
  2. 否则将较小的数的最高位换成5,再乘上10输出。

两个数的长度差为1:(比上面要多一种情况)

  1. 如果较小的数的最高位比5小,就换成5输出(要特判5,50,500,5000......)
  2. 如果较大的数的最高位大于等于5,将较大的数的最高位换成5,输出。
  3. 将较小的的数的最高位上的数加1,然后全接0.(要特判如10,60,300等(高位不用加1))

两个数长度相同:这个我们仔细想一下就会发现如果这两个数的高位相同,那么这些相同的高位可以直接输出了,所以我们放个循环 $ O(n) $ 找到不同的那一位,然后我们发现这一位后面的数可以忽略了(一定会被填成0的,因为贪心第一点:要让最终的价格数的高位上不是0的数尽可能的少)而针对这一位能否填成5,我们又有四中情况:

  1. 这两个数完全相同,这个直接输出
  2. 较小的数的这一位小于5,较大的数的这一位大于5,将这一位改成5输出(不需要特判5,50...这个归到下一类)
  3. 较小的数这一位后面全是0,直接输出
  4. 较小的数这一位后面不全是0,将这一位+1,然后输出。
平心而论:这一题情况并不算多(详见猪国杀)

对了,我们上文有提到一些需要特判的东西,这个只需要,在开始时用一个变量 $ f $ 来记录较小的数从那一位开始之后全是0即可!

$ code: $

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rg register int using namespace std; int t,a,b,f;
char l[11];
char r[11]; inline void qw(char s[],int j,char k,int n){//有这个函数输出就方便多了
for(rg i=0;i<j;++i)putchar(s[i]);
k>'9'?printf("10"):putchar(k);
for(rg i=1;i<=n;++i)putchar('0');
puts("");
} int main(){ cin>>t;
//freopen("Price.in","r",stdin);
//freopen("Price.out","w",stdout);
while(t--){
cin>>l>>r;
f=a=strlen(l)-1;
b=strlen(r)-1;
while(l[f]=='0')--f;//记录从那一位开始后面全是0
if(b-a>1){//差一位以上
if(l[0]<'5'||(l[0]=='5'&&f==0)){qw(l,0,'5',a);continue;}
qw(l,0,'5',a+1);continue;
}if(b-a>0){//差一位
if(l[0]<'5'||(l[0]=='5'&&f==0)){qw(l,0,'5',a);continue;}
if(r[0]>='5'){qw(l,0,'5',b);continue;}
if(f==0){qw(l,0,l[0],a);continue;}
qw(l,0,l[0]+1,a);continue;
}int i=0;while(l[i]==r[i]&&i<=a)++i;//找到不同的哪一位
if(i>a||f<i){qw(l,a,l[a],0);continue;}
if(l[i]<'5'&&r[i]>='5'){qw(l,i,'5',a-i);continue;}
if(f==i){qw(l,i,l[i],a-i);continue;}
qw(l,i,l[i]+1,a-i);
}
return 0;
}

情况都是按上文顺序写的,但本人还是很菜可能思虑不周,欢迎大家来hack(hack成功了麻烦提醒一下,O(∩_∩)O谢谢)

[HEOI2015]定价 (贪心)的更多相关文章

  1. BZOJ 4029: [HEOI2015]定价 贪心

    4029: [HEOI2015]定价 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4029 Description 在市场上有很多商品的 ...

  2. 「BZOJ4029」[HEOI2015] 定价 贪心

    「BZOJ4029」[HEOI2015] 定价 2015年4月28日2,7490 Description 在市场上有很多商品的定价类似于 999 元.4999 元.8999 元这样.它们和 1000 ...

  3. Luogu P4109 [HEOI2015]定价 贪心

    思路:找规律?$or$贪心. 提交:1次 题解: 发现:若可以构成$X0000$,答案绝对不会再在数字最后把$0$改成其他数: 若可以构成$XX50...0$更优. 所以左端点增加的步长是增加的($i ...

  4. 【BZOJ4029】[HEOI2015]定价(贪心)

    [BZOJ4029][HEOI2015]定价(贪心) 题面 BZOJ 洛谷 题解 每次加上十进制下的\(lowbit\)就行了??? #include<iostream> #include ...

  5. 洛谷——P4109 [HEOI2015]定价

    P4109 [HEOI2015]定价 模拟(有点儿贪心) 题目要求在区间$l,r$中$x$后导0尽量多,且除去后导0之外,最后一个数尽量是$5$才最优 从$l$到$r$依次考虑, 假设当前考虑到$50 ...

  6. BZOJ 4029 HEOI2015 定价 数位贪心

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4029 题意概述:对于一个数字的荒谬程度定义如下:删除其所有的后缀0,然后得到的数字长度为a ...

  7. BZOJ 4029 [HEOI2015] 定价 ( 数位DP/贪心 )

    前言 最近学了数位DP,感觉挺简单又实用.这道题就比较水,可以用300B的贪心过掉-网上似乎大多是贪心的题解,我就写写DP的做法 题意 给出正整数区间[L,R][L,R][L,R],定义荒谬值为 (去 ...

  8. [HEOI2015]定价

    题目描述 在市场上有很多商品的定价类似于 999 元.4999 元.8999 元这样.它们和 1000 元.5000 元和 9000 元并没有什么本质区别,但是在心理学上会让人感觉便宜很多,因此也是商 ...

  9. [BZOJ4029][HEOI2015] 定价

    Description 在市场上有很多商品的定价类似于 999 元.4999 元.8999 元这样.它们和 1000 元.5000 元和 9000 元并没有什么本质区别,但是在心理学上会让人感觉便宜很 ...

随机推荐

  1. Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...

  2. BZOJ4538 HNOI2016网络(树链剖分+线段树+堆/整体二分+树上差分)

    某两个点间的请求只对不在这条路径上的询问有影响.那么容易想到每次修改除该路径上的所有点的答案.对每个点建个两个堆,其中一个用来删除,线段树维护即可.由于一条路径在树剖后的dfs序中是log个区间,所以 ...

  3. UVALive5870-Smooth Visualization-模拟水题

    很水的模拟题,拿数组搞就好了. 注意边界的地方不要算重. #include <cstdio> #include <cstring> #include <algorithm ...

  4. The Chinese Postman Problem HIT - 2739(有向图中国邮路问题)

    无向图的问题,如果每个点的度数为偶数,则就是欧拉回路,而对于一个点只有两种情况,奇数和偶数,那么就把都为奇数的一对点  连一条  边权为原图中这两点最短路的值  的边  是不是就好了 无向图中国邮路问 ...

  5. mysql Packet for query is too large (2036 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.

    解决方法: 打开控制台,输入下面语句,执行 set global max_allowed_packet = 20*1024*1024; 网上说要重启 mysql server, 我是执行完后不用重启就 ...

  6. MT【4】坐标平移后齐次化

    简答:通过坐标平移可以将A点移到原点,设BC:mx’+ny’=1,联立坐标变换后的椭圆方程和BC,将$\frac{y}{x}$看成斜率k,得到关于k的一元二次方程,由题意两根之积为-1,可得.

  7. LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)

    题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...

  8. 自学Zabbix5.1 zabbix maintenance维护周期

    自学Zabbix5.1 zabbix maintenance维护周期 1. 概述 你可以定义维护周期在主机或主机组里.这里有2种维护状态: 依旧收集数据   继续对目标的监控数据的收集 暂停收集数据 ...

  9. sharepoint my site setting

    参考这个guide : http://technet.microsoft.com/en-us/library/ee624362.aspx User profile service 不能打开, 原因是s ...

  10. SpringMvc的Url映射和传参案例

    Springmvc的基本使用,包括url映射.参数映射.页面跳转.ajax和文件上传 以前学习的时候写的代码案例,今天整理笔记的时候找到了,很久没有来园子了,发上来当个在线笔记用吧,免的时间长了又忘了 ...