题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5176
There are many Equations. Some are difficult to solve, for example: an xn + an-1 xn-1 + .. + a0 = 0.
In this problem, you are given a simple equation: AX + BY = XY. To simplify the problem, here A, B, X, Y are positive integers. Your task is to find the solution (X, Y) of this equation where X is not less than M. If there are multiple solutions, you should choose the solution with the minimal X + Y. If there are still ties, you should choose the solution with the minimalX.
Input
There are multiple test cases (about 3000). For each test case:
There is only one line contains three integers A, B (1 <= A, B <= 10 ^ 9) and M (1 <= M <= 10 ^ 18).
Output
For each test case, output X and Y. If there is no valid solution, output "No answer" instead.
Sample Input
1 1 2 1 1 3 3 4 8 3 4 9
Sample Output
2 2 No answer 8 6 10 5
Author: LIANG, Mingqiang
Source: ZOJ Monthly, January 2014
题目意思:
给定A,B,M,求方程AX+BY=XY,要求X、Y为整数,且X要大于等于M,且满足X+Y尽可能小,如果再相同取X较小的。
解题思路:
原方程等价于(X-B)(Y-A)=XY
先用素数筛选法筛选出1000000内的所有质数。
然后将A、B分解质因数,并把相同的质因数合并,然后dfs,对每个质因数枚举分给第一部分的个数,然后剩余的全部给第二部分,然后结束时比较X+Y与之前保存的值,看是否要更新。
代码:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF ((1LL)<<(60LL))
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define N 1000000
#define Maxn 1100000
int prime[Maxn],cnt;
bool isp[N+100];
map<LL,int>myp;
LL a,b,m,Max,ansa,ansb;
map<LL,int>::iterator it;
void init() //素数筛选法筛出1000000内的质因数
{
cnt=0;
for(int i=0;i<=N;i++)
isp[i]=true;
for(int i=2;i<=N;i++)
{
if(!isp[i])
continue;
prime[++cnt]=i;
for(int j=i;j<=N;j+=i)
isp[j]=false;
}
//printf("%d\n",cnt);
}
void get(LL cur) //分解质因数并合并
{
for(int i=1;i<=cnt&&prime[i]*prime[i]<=cur;i++)
{
if(cur%prime[i]==0)
{
while(cur%prime[i]==0)
{
myp[prime[i]]++;
cur/=prime[i];
}
}
}
if(cur!=1)
myp[cur]++;
}
void dfs(LL aa,LL bb,map<LL,int>:: iterator cur) //对每个质因数枚举分给两部分的个数
{
LL temp=cur->first;
int tt=cur->second;
//printf("aa:%lld bb:%lld temp:%lld tt:%d\n",aa,bb,temp,tt);
//system("pause");
if(cur==myp.end())
{
if(aa+b>=m)
{
//printf("sum:%lld max:%lld\n",aa+b+bb+a,Max);
//system("pause");
if(aa+b+bb+a<Max)
{
Max=aa+b+bb+a;
ansa=aa+b;
ansb=bb+a;
}
else if(aa+b+bb+a==Max&&aa+b<=ansa) //相等的情况下保存较小的x
{
ansa=aa+b;
ansb=bb+a;
}
}
return ;
}
for(int i=0;i<=tt;i++)
{
cur++;
dfs(aa*(LL)pow(temp,i),bb*(LL)pow(temp,tt-i),cur);
cur--;
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
init();
while(~scanf("%lld%lld%lld",&a,&b,&m))
{
myp.clear();
get(a);
get(b);
it=myp.begin();
Max=INF;
//printf("%lld\n",Max);
dfs(1,1,it);
if(Max==INF)
printf("No answer\n");
else
printf("%lld %lld\n",ansa,ansb);
//printf("%d\n",myp.size());
}
return 0;
}