题目链接:点击打开链接
Description
You have two friends. You want to present each of them several positive integers. You want to presentcnt1 numbers to the first friend andcnt2 numbers to the second friend. Moreover, you want all presented numbers to be distinct, that also means that no number should be presented to both friends.
In addition, the first friend does not like the numbers that are divisible without remainder by prime numberx. The second one does not like the numbers that are divisible without remainder by prime numbery. Of course, you're not going to present your friends numbers they don't like.
Your task is to find such minimum numberv, that you can form presents using numbers from a set1, 2, ..., v. Of course you may choose not to present some numbers at all.
A positive integer number greater than 1 is calledprime if it has no positive divisors other than 1 and itself.
Input
The only line contains four positive integerscnt1, cnt2, x,y (1 ≤ cnt1, cnt2 < 109;cnt1 + cnt2 ≤ 109;2 ≤ x < y ≤ 3·104) — the numbers that are described in the statement. It is guaranteed that numbersx, y are prime.
Output
Print a single integer — the answer to the problem.
Sample Input
3 1 2 3
5
1 3 2 3
4
Sample Output
Hint
In the first sample you give the set of numbers{1, 3, 5} to the first friend and the set of numbers{2} to the second friend. Note that if you give set{1, 3, 5} to the first friend, then we cannot give any of the numbers1, 3, 5 to the second friend.
In the second sample you give the set of numbers{3} to the first friend, and the set of numbers {1, 2, 4} to the second friend. Thus, the answer to the problem is 4.
题目大意:讲述的是一个人送他两朋友(假设为A B)数字,其中A不喜欢素数X,B不喜欢素数Y,所以送他们地数字不能是XY的倍数;输入有四个数字代表A不喜欢的数字,B不喜欢的数字;给出的一个范围的一边i ,j(分别针对A B );求一个最小数n满足i;j 与它构成的范围中有数满足·送数条件。
题目分析:这道题如果用暴力枚举的话肯定不可行,在网上和学长的指导下终于找到了一个实用简单的方法,进行二分查找。
要点及注意事项:这道题估计最简单的方法就是二分查找了;值得注意的就是二分上限,结合各数据大小分析可得。
AC代码----借鉴方法就可以了(二分查找)
大神的代码——--------------
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int n,m,x,y,median;
while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF)
{
int l=2,ans=2e9+1;
while(l<ans)
{
median=l+ans/2;
if(n<=(median-median/x)&&m<=(median-median/y)&&n+m<=median-median/(x*y))
ans=median;
else
l=median+1;
}
printf("%d\n",ans);
}
return 0;
}
#include<stdio.h>
int main()
{
int cn1,cn2,i,j,x,y;//flag来标记x,y的公倍数
while(scanf("%d%d%d%d",&cn1,&cn2,&x,&y)!=EOF){
int n1=0,n2=0,flag=0;//n1,n2记录送给第一个人和第二个人数字的个数
for(i=1;n1<cn1||n2<cn2;i++){//当n1和n2同时达到目标cn1,cn2时结束
if(i%y!=0&&i%x!=0&&n1<cn1)
flag++;
if(i%x!=0&&n1<cn1)//当n1<cn1时,先保证第一个人达到要求
n1++;
else if(i%y!=0)
n2++;
else if(i%y==0&&i%x!=0&&flag>0){
n2++;
flag--;
}
//当第一个人达到要求后出现了满足第一个人而不满足第二个人时,
//让第一个人用他满足第二个人又满足第一个人的数与第二个人交换。
<pre name="code" class="cpp"><span style="font-family: Arial, Helvetica, sans-serif;">//注意如果交换完了怎么办?</span>
} printf("%d\n",i-1); } return 0;}
心得:AC了这道题最大感悟就是,有时候可以把问题换个角度想下,比如二分就比暴力枚举更高效有力,暴力枚举一不小心就超时了