基于求最大公约数的数学题
Monitor
描述:
Reca company makes monitors, the most popular of their models is AB999 with the screen size a?×?b centimeters. Because of some production peculiarities a screen parameters are integer numbers. Recently the screen sides ratio x:?y became popular with users. That's why the company wants to reduce monitor AB999 size so that its screen sides ratio becomes x:?y, at the same time they want its total area to be maximal of all possible variants. Your task is to find the screen parameters of the reduced size model, or find out that such a reduction can't be performed.
Reca公司生产显示器,他们最流行的型号是屏幕尺寸为a的AB999?×?b厘米。由于某些生产特性,屏幕参数为整数。最近,屏幕边长比x:?y开始受到用户的欢迎。这就是为什么该公司希望缩小显示器AB999的尺寸,使其屏幕边长比变成x:?y、 同时,他们希望它的总面积是所有可能变体中最大的。您的任务是找到缩小模型的屏幕参数,或者发现这样的缩小无法执行。
输入:
The first line of the input contains 4 integers — a, b, x and y (1?≤?a,?b,?x,?y?≤?2·109).
输出:
If the answer exists, output 2 positive integers — screen parameters of the reduced size model. Output 0 0 otherwise.
样例输入:
800 600 4 3
样例输出:
800 600
样例输入:
1920 1200 16 9
样例输出:
1920 1080
样例输入:
1 1 1 2
当时我是如何想的?当时我也考虑到了x,y可能比a,b都要大,所以要化简x,y,即求出他们的最大公约数;
1.如果还比a,b大,则输出0 0;
2.如果1没出现,则看一下a/b=x/y;即b=(a*y)/x是否为整数,而且要满足a>b,x>y才满足最大屏幕的情况
1920 1200 16 9 如个样例;
当条件多起来就很麻烦,又要分x,y的大小情况,有要分a,b的大小情况;
3.如果不能整除,就基于 x:y 的比例不断乘以一个数num直到他们x*num<=a && y*num<=b (其实我这个想法已经快接近正确答案了)
可惜,明明3 的想法也可以包含2 的情况,我当时傻了去枚举2的那么多种情况;而且我在写3 时也去枚举我要乘的数num去了(我到底多喜欢在不该枚举的地方枚举呀)
于是就有了下面这个又长又臭,还错了的代码:
#include#include using namespace std; int main() { int prix,priy,needx,needy; cin>>prix>>priy>>needx>>needy; int a,b,mid; a=needx; b=needy; while (b) { mid=b; b=a%b; a=mid; } needx/=a; needy/=a; if (prix needy) { printf ("0 0"); } else { if (needx%needy==0 && needx/needy==1) { int num=min(prix,priy); printf ("%d %d",num,num); } else { if (prix>priy) { if (needx>needy) { if ((prix*needy)%needx==0) { printf ("%d %d",prix,(prix*needy)/needx); } else { int chushu=min(int(prix/needx),int(priy/needy)); int i; for (i=chushu;i*needx<=prix && i*needy<=priy;i++); printf ("%d %d",(i-1)*needx,(i-1)*needy); } } else { if ((priy*needx)%needy==0) { printf ("%d %d",(priy*needx)/needy,priy); } else { int chushu=min(int(prix/needx),int(priy/needy)); int i; for (i=chushu;i*needx<=prix && i*needy<=priy;i++); printf ("%d %d",(i-1)*needx,(i-1)*needy); } } } else if (prix<priy) { if (needx>needy) { if ((prix*needy)%needx==0) { printf ("%d %d",prix,(prix*needy)/needx); } else { int chushu=min(int(prix/needx),int(priy/needy)); int i; for (i=chushu;i*needx<=prix && i*needy<=priy;i++); printf ("%d %d",(i-1)*needx,(i-1)*needy); } } else { if ((priy*needx)%needy==0) { printf ("%d %d",(priy*needx)/needy,priy); } else { int chushu=min(int(prix/needx),int(priy/needy)); int i; for (i=chushu;i*needx<=prix && i*needy<=priy;i++); printf ("%d %d",(i-1)*needx,(i-1)*needy); } } } else if (prix==priy) { int minnum=min(needx,needy); int maxnum=max(needx,needy); if ((prix*minnum)%maxnum==0) { if (needx>needy) { printf ("%d %d",prix,(prix*minnum)/maxnum); } else { printf ("%d %d",(prix*minnum)/maxnum,priy); } } else { int chushu=min(int(prix/needx),int(priy/needy)); int i; for (i=chushu;i*needx<=prix && i*needy<=priy;i++); printf ("%d %d",(i-1)*needx,(i-1)*needy); } } } } return 0; }
接下来说下正确的代码:
1 #include2 #include 3 using namespace std; 4 int main() 5 { 6 int prix,priy,needx,needy; 7 cin>>prix>>priy>>needx>>needy; 8 int a,b,mid; 9 a=needx; 10 b=needy; 11 while (b) 12 { 13 mid=b; 14 b=a%b; 15 a=mid; 16 } 17 needx/=a; 18 needy/=a; 19 int t=min(prix/needx,priy/needy); 20 cout<<(t*needx)<<" "<<(t*needy); 21 return 0; 22 }
第19行代码就可以满足我2.3思想的全部情况,当然不用担心不能被整除的情况,因为t一直是个整数,t乘以needx,neey一定不会超过prix或priy,且一定满足最大屏幕这个条件;
接下来,不得不说一下关于求最大公约数的方法了:
https://blog.csdn.net/qq_52441682/article/details/118875299?spm=1001.2014.3001.5502
我学长的博客将的很清楚了;