zoukankan      html  css  js  c++  java
  • 定价(Price)

      传送门

    【题目描述】
      在市场上有很多商品的定价类似于 999 元、4999 元、8999 元这样。它们和 1000 元、5000 元和 9000 元并没有什么本质区别,但是在心理学上会让人感觉便宜很多,因此也是商家常用的价格策略。不过在你看来,这种价格十分荒谬。于是你如此计算一个价格 p(p为正整数)的荒谬程度:
      1、首先将 p 看做一个由数字组成的字符串(不带前导 0);
      2、然后,如果 p 的最后一个字符是 0,就去掉它。重复这一过程,直到 p 的最后一个字
      符不是 0;
      3、记 p 的长度为 a,如果此时 p 的最后一位是 5,则荒谬程度为 2 * a - 1;否则为 2* a。
      例如,850 的荒谬程度为 3,而 880 则为 4,9999 的荒谬程度为 8。
       现在,你要出售一样闲置物品,你能接受的定价在 [L, R] 范围内,你想要给出一个荒谬度最低的价格。
    【输入】
        输入文件的第一行包含一个正整数 T,表示测试数据的数目。
        每个测试数据占单独的一行,包含两个空格分隔的正整数 L, R,表示定价的区间。
    【输出】
         对于每个测试数据,在单独的一行内输出结果。如果荒谬度最低的价格不唯一,输出最小的那个。
    【样例】
      Price.in
      3
      998 1002
      998 2002
      4000 6000
      price.out
      1000
      1000
      5000
    【数据范围】
      30 % 数据 1 <= L <= R <= 10^4
      对于 100% 的数据,T ≤ 100,1 ≤ L ≤ R ≤ 10^9.

    我的思路:

      我发现我的想法和大家都不一样??

      经过无数次修改 终于A了这道题  (为此,我还学了对拍)

      首先说一个大家都知道的推论 :

        就是把一个数的最后一个非零数凑成10也就是0的答案会比凑成5的答案更优

      于是我初始化 ans=L  

      然后每次都找到 ans 的最后一个非0位

      先判断是否可以凑成0

      如果可以的话就继续循环 否则就尝试把最后一位凑成5

      不管可不可以凑成5 都直接返回答案

      但是这是有bug的 这样子的答案一定是荒谬值最小的没有错

      但却不一定是最小的答案

      一组hack数据: 67  400  

      按照我的思路就会输出 100

      这组数据中 把 70 凑成100 对答案是没有贡献的

      所以有了我代码中的tmp 就是用来解决这个问题的

      tmp 储存 当答案的非零位第一次只有一位时的答案

      成为可能的答案

      那么它什么时候才能变成真正的答案呢

      只有当到最后凑不出5的时候才是

      因为非0位只有1位了 再怎么凑也是1位

      只有凑成了一位的5才会成为更优的答案


      我不得不说真的有点难实现

    CODE: 

     1 #include<iostream>
     2 #include<cstdio>
     3 #define go(i,a,b) for(register int i=a;i<=b;i++)
     4 #define yes(i,a,b) for(register int i=a;i>=b;i--)
     5 #define ll long long
     6 #define db double
     7 #define inf 210000000000
     8 using namespace std;
     9 ll read()
    10 {
    11     ll x=0,y=1;char c=getchar();
    12     while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
    13     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    14     return x*y;
    15 }
    16 ll T,l,r,y,z,ans,res,tmp;
    17 bool ck1()  //凑成0
    18 {
    19     ll x=10-ans%10;if(x==10) x=0;
    20     if((ans+x)*y<=r)
    21     {
    22         ans+=x;ans/=10;y*=10;
    23         if(ans<z) {res--;z/=10;}
    24         return 1;
    25     }
    26     return 0;
    27 }
    28 bool ck2() //凑成5
    29 {
    30     ll x=5-ans%10;
    31     if(x<0) return 0;
    32     if((ans+x)*y<=r)
    33     {
    34         ans+=x;
    35         return 1;
    36     }
    37     return 0;
    38 }
    39 ll work()
    40 {
    41     while(!(ans%10)) {ans/=10;y*=10;}
    42     int x=1; while(ans>=x) {x*=10;res++;z*=10;}z/=10;
    43     while(1)
    44     {
    45         if(ans<=5) {if(!ck2() && tmp!=inf) return tmp ;return ans*y;}
    46         if(res==1) tmp=ans*y;
    47         if(!ck1())
    48         {
    49             ck2();
    50             if(res==1&&ans!=5&&tmp!=inf) return tmp;
    51             return ans*y;
    52         }
    53     }
    54 }
    55 int main()
    56 {
    57     freopen("1.in","r",stdin);
    58     freopen("1.out","w",stdout);
    59     T=read();
    60     while(T--)
    61     {
    62         l=read();r=read();
    63         ans=l;res=0;y=1;z=1;tmp=inf;
    64         printf("%lld
    ",work());
    65     }
    66     return 0;
    67 }
    View Code

      这题还有几个别的方法啊 希望落实完别的题目可以去学习一下 然后再来总结辣  

      然后先贴上 hss的题解      看起来很详细的样子

    光伴随的阴影
  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/forward777/p/10330382.html
Copyright © 2011-2022 走看看