September 24th 模拟赛C T1 电费结算 Solution

空降题目处(外网)
点我点我点我

空降题目处(内网)
点我点我点我

Description

WZK最近靠租房发家致富了。作为WZK老同学的你也要租房,于是WZK决定不要房租,但是电费还得付。以下是用电价格:
这里写图片描述
举个例子吧。如果你用电为10123千瓦时,那么要付2 * 100 + 3 * 9900 + 5 * 123 = 30515块钱(好贵)。
到结算电费的日子了,可是WZK家里只有一个总电表,也就是统计你和WZK总共用的电量。但是WZK有办法告诉你以下信息:
1).如果按照总电表来看要交给供电局的钱A。(也就是两个人用电量加起来一起算钱)
2).你和WZK如果分开付的话,你们付的钱的差值B。
现在你想知道如果你单独算钱的话,需要付多少钱。当然,你的用电量不会比WZK多。
举个例子:如果你们一起算钱要付1100,并且如果分开来算,你们的差值是300的话,那么你用了150kwh,WZK用了250kwh。让我们来验算一下:你们一共用电400kwh,所以要付2 * 100 + 3 * 300 = 1100,你单独要付2 * 100 + 3 * 50 = 350,WZK单独要付2 * 100 + 3 * 150 = 650。所以最后,你只需要告诉我你单独要付350元。

Input

输入仅一行,包含两个整数A和B(1 ≤ A, B ≤ 10^9),含义同上。 输出描述: 输出仅一行一个整数,代表你单独算需要付的钱。数据保证解唯一。

Output

输出仅一行一个整数,代表你单独算需要付的钱。数据保证解唯一。

Solution

利用 A <script type="math/tex" id="MathJax-Element-1">A</script>求出总电量,然后二分自己的电量,判断对错.

Code

C++

#include<fstream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

int a,b,n;

int bs(int l,int r);

int main()
{
    //freopen("init.in","r",stdin);
    scanf("%d%d",&a,&b);
    if (a>4979900)
        n=(a-4979900)/7+1000000;
    else
        if (a>29900)
            n=(a-29900)/5+10000;
        else
            if (a>200)
                n=(a-200)/3+100;
            else
                n=a/2;
    int t=n-bs(n/2,n);
    printf("%d",min(t,100)*2+(max(min(t,10000),100)-100)*3+(max(min(t,1000000),10000)-10000)*5+(max(min(t,1000000000),1000000)-1000000)*7);
}

int bs(int l,int r)
{
    if (l>=r)
        return l;
    int m=(l+r)/2;
    if ((min(m,100)*2+(max(min(m,10000),100)-100)*3+(max(min(m,1000000),10000)-10000)*5+(max(min(m,1000000000),1000000)-1000000)*7)-b<(min((n-m),100)*2+(max(min((n-m),10000),100)-100)*3+(max(min((n-m),1000000),10000)-10000)*5+(max(min((n-m),1000000000),1000000)-1000000)*7))
        return bs(m+1,r);
    else
        return bs(l,m);
}

Pascal

var
        n,m,i,j,k,x,y,t,l,r,mid:longint;
function max(x,y:longint):longint;
begin
        if x>y then exit(x) else exit(y);
end;
begin
        read(n,m);
        if n>4979900 then t:=(n-4979900) div 7+1000000 else
        if n>29900 then t:=(n-29900) div 5+10000 else
        if n>200 then t:=(n-200) div 3+100 else t:=n div 2;
        l:=1;
        r:=t div 2;
        while l<r do
        begin
                mid:=(l+r) div 2;
                if mid>1000000 then x:=(mid-1000000)*7+4979900 else
                if mid>10000 then x:=(mid-10000)*5+29900 else
                if mid>100 then x:=(mid-100)*3+200 else x:=mid*2;
                k:=t-mid;
                if k>1000000 then y:=(k-1000000)*7+4979900 else
                if k>10000 then y:=(k-10000)*5+29900 else
                if k>100 then y:=(k-100)*3+200 else y:=k*2;
                if y-x=m then
                begin
                        write(x);
                        halt;
                end;
                if y-x>m then l:=mid+1 else r:=mid;
        end;
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值