[CF1538G] Gift Set (数学简单题)
题面
有
x
\tt x
x 个红糖,
y
\tt y
y 个蓝糖。每一个礼包里面要么有
a
\tt a
a 个红糖+
b
\tt b
b 个蓝糖,要么是
a
\tt a
a 个蓝糖+
b
\tt b
b 个红糖。
问最多能打多少份礼包。
T
≤
1
0
4
\tt T\leq 10^4
T≤104 组数据,
1
≤
x
,
y
,
a
,
b
≤
1
0
9
\tt1\leq x,y,a,b\leq10^9
1≤x,y,a,b≤109 。
题解
Solution #1
不难发现答案具有包含性,能打
n
\tt n
n 份就一定能打
n
−
1
\tt n-1
n−1 份。
交换,令
a
≥
b
\tt a\geq b
a≥b,那么每打包一份礼包,
x
\tt x
x 和
y
\tt y
y 都至少会减少
b
\tt b
b。
直接二分答案
s
\tt s
s,那么在
x
,
y
≥
s
⋅
b
\tt x,y\geq s\cdot b
x,y≥s⋅b 的前提下,再把
x
\tt x
x 和
y
\tt y
y 都减去
s
⋅
b
\tt s\cdot b
s⋅b 后,相当于在
x
,
y
\tt x,y
x,y 中只用找单独的
s
\tt s
s 个
a
−
b
\tt a-b
a−b 就行了(
{
x
,
y
}
\tt\{x,y\}
{x,y} 变成了
{
x
−
s
b
,
y
−
s
b
}
\tt\{x-sb,y-sb\}
{x−sb,y−sb},
{
a
,
b
}
\tt\{a,b\}
{a,b} 变成了
{
a
−
b
,
0
}
\tt\{a-b,0\}
{a−b,0},其中一个为 0 了,两种糖果不再绑定),这等价于此时
a
=
b
\tt a=b
a=b 或者
⌊
x
a
−
b
⌋
+
⌊
y
a
−
b
⌋
≥
s
\tt\left\lfloor\frac{x}{a-b}\right\rfloor+\left\lfloor\frac{y}{a-b}\right\rfloor\geq s
⌊a−bx⌋+⌊a−by⌋≥s 。
直到这里,都没怎么用脑子。
7
m
i
n
\tt7~min
7 min 过掉,总复杂度
O
(
T
log
)
\tt O(T\log)
O(Tlog),速度还行,
31
m
s
\tt31~ms
31 ms。
CODE
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
int X,Y,A,B;
bool check(int md) {
int x=X,y=Y,a=A,b=B;
if(x < md*1ll*B || y < md*1ll*B) return 0;
x -= md*1ll*B; y -= md*1ll*B; a -= b;
if(a == 0) return 1;
return x/a + y/a >= md;
}
int main() {
int T = read();
while(T --) {
X = read();Y = read();
A = read();B = read();
if(X < Y) swap(X,Y);
if(A < B) swap(A,B);
int as = 0;
for(int i = 30;i >= 0;i --) {
if(as+(1<<i) <= 1000000000 && check(as+(1<<i))) {
as += (1<<i);
}
}
printf("%d\n",as);
}
return 0;
}
Solution #2
不妨交换,令
x
≥
y
,
a
≥
b
\tt x\geq y,a\geq b
x≥y,a≥b 。
然后利用一定的贪心思路,不难发现,最优情况下
(
a
,
b
)
\tt(a,b)
(a,b) 的个数一定不小于
(
b
,
a
)
\tt(b,a)
(b,a)。换言之,我们可以认为有若干个权重为 1 的礼包
(
a
,
b
)
\tt(a,b)
(a,b),以及若干个权重为 2 的礼包
(
a
+
b
,
b
+
a
)
\tt(a+b,b+a)
(a+b,b+a).
先特判
a
=
b
\tt a=b
a=b 的情况,再继续讨论。
为了尽量地利用糖果,使之剩下的最少(每个礼包固定消耗
a
+
b
\tt a+b
a+b,因此剩下最少一定意味着礼包最多),那么就要尽量使最终的
∣
x
−
y
∣
\tt|x-y|
∣x−y∣ 最小化。由于每一份礼包 1 都能减少差值
a
−
b
\tt a-b
a−b ,那么我们就令礼包
(
a
,
b
)
\tt(a,b)
(a,b) 的个数为
⌊
x
−
y
a
−
b
⌋
\tt\left\lfloor\frac{x-y}{a-b}\right\rfloor
⌊a−bx−y⌋ ,然后再利用剩下的求出礼包 2 的个数、贡献。
为了调整出正确答案,我们还得求一求礼包 1 个数为
⌊
x
−
y
a
−
b
⌋
+
1
\tt\left\lfloor\frac{x-y}{a-b}\right\rfloor+1
⌊a−bx−y⌋+1 的情况,再取更优值。毕竟有些边角情况,原先的下取整是考虑不到的。
时间复杂度
O
(
T
)
\tt O(T)
O(T) ,写得一般的还是
31
m
s
\tt31~ms
31 ms,而且想的比较久。
CODE(by SharpnessⅤ)
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
#define N 500005
using namespace std;
int x,y,a,b;
void solve(){
scanf("%d%d%d%d",&x,&y,&a,&b);
if(x>y)swap(x,y);if(a>b)swap(a,b);
if(x<a||y<b){puts("0");return ;}
int res=y-x,lim=b-a;
if(!lim){
printf("%d\n",min(x,y)/a);
return ;
}
int cur=min(res/lim,min(x/a,y/b));
x-=cur*a,y-=cur*b;int ans=cur+min(x,y)/(a+b)*2;
if(x>=a&&y>=b)x-=a,y-=b,cur++;
printf("%d\n",max(ans,cur+min(x,y)/(a+b)*2));
}
int main(){
int T;scanf("%d",&T);
while(T--)solve();
return 0;
}
[CF1538G] Gift Set (数学简单题)的更多相关文章
- hihoCoder #1234 : Fractal(数学简单题)
时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 This is the logo of PKUACM 2016. More specifically, the logo i ...
- PJ考试可能会用到的数学思维题选讲-自学教程-自学笔记
PJ考试可能会用到的数学思维题选讲 by Pleiades_Antares 是学弟学妹的讲义--然后一部分题目是我弄的一部分来源于洛谷用户@ 普及组的一些数学思维题,所以可能有点菜咯别怪我 OI中的数 ...
- acm.njupt 1001-1026 简单题
点击可展开上面目录 Acm.njupt 1001-1026简单题 第一页许多是简单题,每题拿出来说说,没有必要,也说不了什么. 直接贴上AC的代码.初学者一题题做,看看别人的AC代码,寻找自己的问题. ...
- 天哪!毫无思绪!令人感到恐惧的数学(水题?)(TOWQs)
这道题的题目描述灰常简单,第一眼看以为是一道十分水的题目: 但是!!!(我仔细一看也没有发现这背后隐藏着可怕的真相~) 下面给出题目描述: 给出一个整数x,你可以对x进行两种操作.1.将x变成4x+3 ...
- BZOJ 2683: 简单题
2683: 简单题 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 913 Solved: 379[Submit][Status][Discuss] ...
- 【BZOJ-1176&2683】Mokia&简单题 CDQ分治
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- Bzoj4066 简单题
Time Limit: 50 Sec Memory Limit: 20 MBSubmit: 2185 Solved: 581 Description 你有一个N*N的棋盘,每个格子内有一个整数,初 ...
- Bzoj2683 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1071 Solved: 428 Description 你有一个N*N的棋盘,每个格子内有一个整数, ...
- 这样leetcode简单题都更完了
这样leetcode简单题都更完了,作为水题王的我开始要更新leetcode中等题和难题了,有些挖了很久的坑也将在在这个阶段一一揭晓,接下来的算法性更强,我就要开始分专题更新题目,而不是再以我的A题顺 ...
随机推荐
- 前端工作中用到的openlayers相关的公共方法
/** * 获取地图上的图层对象 * @param map 地图对象 * @param layerName 实例化图层时的name * @return {null}*/ getLayerByLayer ...
- Redis之Lua的应用(四)
一.什么是Lua脚本 Lua是一个高效的轻量级脚本语言(和JavaScript类似),用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能.Lu ...
- SAP Web Dynpro-版本管理
您可以使用版本管理来管理对象的旧版本,比较版本,也可以重置它们. 在版本管理中,您可以存储ABAP开发对象的不同版本. 在ABAP工作台中,您可以比较不同版本的- 视图 视窗 控制器 您也可以存储对象 ...
- Windows启动谷歌浏览器Chrome失败(应用程序无法启动,因为应用程序的并行配置不正确)解决方法
目录 一.系统环境 二.问题描述 三.解决方法 一.系统环境 Windows版本 系统类型 浏览器Chrome版本 Windows 10 专业版 64 位操作系统, 基于 x64 的处理器 版本 10 ...
- web文本划线的极简实现
开篇 文本划线是目前逐渐流行的一个功能,不管你是小说阅读网站,还是卖教程的的网站,一般都会有记笔记或者评论的功能,传统的做法都是在文章底部加一个评论区,优点是简单,统一,缺点是不方便对文章的某一段或一 ...
- python+requests+yaml实现接口自动化用例(二)---升级版
一.前言:前面一段时间封装的接口自动化测试框架用了一段时间发现还是有很多弊端的,目前又改良了一下,可以说整体思路全都推翻了,功能比之前强大许多,有兴趣的可以私信我单独交流,希望共同学习进步! 二.项目 ...
- go: 如何编写一个正确的udp服务端
udp的服务端有一个大坑,即如果收包不及时,在系统缓冲写满后,将大量丢包. 在网上通常的示例中,一般在for循环中执行操作逻辑.这在生产环境将是一个隐患.是的,俺就翻车了. go强大简易的并发能力可以 ...
- TypeScript ReadonlyArray(只读数组类型) 详细介绍
1.ReadonlyArray 简介 在TypeScript中,除了Array<T>类型,还有一个ReadonlyArray<T>类型,ReadonlyArray类型和Arra ...
- NC24622 Brownie Slicing
NC24622 Brownie Slicing 题目 题目描述 Bessie has baked a rectangular brownie that can be thought of as an ...
- 如何搭建android源代码repo仓库
如何搭建android源代码repo仓库 目录 如何搭建android源代码repo仓库 1 repo是如何管理仓库的? 1.1 repo如何工作的? 1.2 搭建repo服务需要做哪些事情? 2 部 ...