zoukankan      html  css  js  c++  java
  • 题解 P4109 【[HEOI2015]定价】

    莫名其妙冲到了最优解?

    题目链接

    Solution [HEOI2015]定价

    题目大意:设一个数 (x) 去掉后缀零之后为 (x'),长度为 (a) ,定义 (x) 的荒谬度为 (2a-[x';mod;10;=5]),多组询问,求 ([L,R]) 内荒谬度最小的数(荒谬度相同则取最小的数)

    贪心


    分析:

    首先(x')肯定是越短越好,其次再考虑有没有(5)的问题

    我们枚举(p in[0,10]),表示(x)后缀(0)的个数

    那么(x=x' imes 10^p)

    (L=lceil{frac{l}{10^p}} ceil,R= lfloor{frac{r}{10^p}} floor),我们可以确定(x'in [L,R])

    要使得长度最短,我们肯定选(L)这个数,考虑到末尾可能有(5),我们在([L,L+10])中找最优解即可

    各种上下界都比较松,这样比较好写

    #include <cstdio>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    inline int calc(int x){
    	int flag = 0,res = 0;
    	if(x % 10 == 5)flag = -1;
    	do{
    		if(x % 10){
    			if(!flag){
    				if(x % 10 == 5)flag = -1;
    				else flag = 1;
    			}
    		}
    		if(flag != 0)res += 2;
    		x /= 10;
    	}while(x);
    	return res + (flag == -1 ? -1 : 0);
    }
    inline void solve(){
    	int ans = 0,hm = 0x7fffffff,l,r;
    	scanf("%d %d",&l,&r);
    	ll now = 1;
    	for(int i = 0;i <= 10;i++){
    		int L = ceil(double(l) / now),R = r / now;
    		if(L > R)break;
    		for(int i = L;i <= L + 10 && i <= R;i++)
    			if(calc(i) < hm)ans = i * now,hm = calc(i);
    		now *= 10;
    	}
    	printf("%d
    ",ans);
    }
    int t;
    int main(){
    #ifdef LOCAL
    	freopen("fafa.in","r",stdin);
    #endif
    	scanf("%d",&t);
    	while(t--)solve();
    	return 0;
    }
    
  • 相关阅读:
    python IDE比较与推荐
    一个平庸程序员的想法
    [转载]Malcolm的新书:Outliers
    程序员的编辑器——VIM
    Blender网络资源
    普通人的编辑利器——Vim
    易学易用的Windows PowerShell
    分区表的修复(转)
    云南电信DNS服务器地址
    滇南本草(上)
  • 原文地址:https://www.cnblogs.com/colazcy/p/13771880.html
Copyright © 2011-2022 走看看