ZOJ 3753 Simple Equation

来源:互联网 发布:快乐家族关系知乎 编辑:程序博客网 时间:2024/06/05 19:01

[题意]让你解这样一个方程:AX+BY=XY。给定A、B(1<=A,B<=10^9)和M,其中A>=M。让你求X和Y(X,Y>0),其中要求X+Y尽可能小,X尽可能小(优先级递减)。

[分析]将方程变形,可以得到结果:(X-B)(Y-A)=AB。再考虑到X和Y均为正整数,X>=M,问题就转化为分解A和B。

WA了好多次,在将A和B的质因数进行合并的时候出现了问题,我简直是太渣了。。。

#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define Zero(v) memset(v, 0, sizeof(v))typedef long long lld;const int maxn = 100010;const int MAX = 5555;const int INF = 1000000000;int fac1[100], fac2[100];int ret1[100], ret2[100];int fac[100], ret[100]; int prime[maxn];int tot;bool mk[maxn], OK;lld ansX, ansY;void init() {Zero(mk);for(int i=2; i*i<maxn; i++) {if(!mk[i]) {for(int j=i*i; j<maxn; j+=i) mk[j] = 1;}}tot = 0;for(int i=2; i<maxn; i++) {if(!mk[i]) prime[tot++] = i;}}void split(lld n, int* fac, int* ret, int &cnt) {lld m = n;for(int i=0; i<tot && prime[i]*prime[i]<=n; i++) {if(m%prime[i] == 0) {int tmp = 0;fac[cnt] = prime[i];while(m%prime[i] == 0) {m /= prime[i];tmp ++;}ret[cnt++] = tmp;}}if(m > 1) fac[cnt] = m, ret[cnt++] = 1;}lld modPow(int n, int m) {lld ret = 1;for(; m; m>>=1, n=n*n) {if(m&1) ret *= n;}return ret;}void dfs(lld A, lld B, lld M, lld cur, int step, int cnt) {if(step == cnt) {lld X = cur + B;lld Y = A*B/cur + A;if(X >= M) {if(!OK) {ansX = X;ansY = Y;}OK = true;if(X+Y < ansX+ansY) {ansX = X;ansY = Y;} else if(X+Y == ansX+ansY) {if(X < ansX) {ansX = X;ansY = Y;}}}return ;}for(int i=0; i<=ret[step]; i++) {dfs(A, B, M, cur*modPow(fac[step], i), step+1, cnt);}}void gao(lld A, lld B, lld M) {int cnt1 = 0, cnt2 = 0;split(A, fac1, ret1, cnt1);split(B, fac2, ret2, cnt2);int cnt = 0;fac[cnt] = 1;ret[cnt++] = 1;int i = 0, j = 0;while(i < cnt1 || j < cnt2) {if(i >= cnt1 && j >= cnt2) break;if(i >= cnt1) {fac[cnt] = fac2[j];ret[cnt] = ret2[j];cnt++; j++;if(j >= cnt2) break;continue;}if(j >= cnt2) {fac[cnt] = fac1[i];ret[cnt] = ret1[i];cnt++; i++;if(i >= cnt1) break;continue;}if(fac1[i] > fac2[j]) {fac[cnt] = fac2[j];ret[cnt] = ret2[j];cnt++; j++;continue;}if(fac1[i] < fac2[j]) {fac[cnt] = fac1[i];ret[cnt] = ret1[i];cnt++; i++;continue;}if(fac1[i] == fac2[j]) {fac[cnt] = fac1[i];ret[cnt] = ret1[i] + ret2[j];cnt++; i++; j++;continue;}}//while(i < cnt1 || j < cnt2) {//if((i<cnt1 && j<cnt2 && fac1[i]<fac2[j]) || (j==cnt2 && i<cnt1)) {//fac[cnt] = fac1[i];//ret[cnt] = ret1[i];//cnt++; i++;//}//else if((i<cnt1 && j<cnt2 && fac1[i]>fac2[j]) || (i==cnt1 && j<cnt2)) { //fac[cnt] = fac2[j];//ret[cnt] = ret2[j];//cnt++; j++;//}//else if(i<cnt1 && j<cnt2 && fac1[i]==fac2[j]) {//fac[cnt] = fac1[i];//ret[cnt] = ret1[i] + ret2[j];//cnt++; i++; j++;//}//}OK = false;dfs(A, B, M, 1, 0, cnt);if(OK) printf("%lld %lld\n", ansX, ansY);else puts("No answer");}int main() {lld A, B, M;init();while(scanf("%lld%lld%lld", &A, &B, &M) != EOF) {gao(A, B, M);}return 0;}


0 0
原创粉丝点击