HDU3113(工科数学分析之分解)
生活随笔
收集整理的這篇文章主要介紹了
HDU3113(工科数学分析之分解)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:http://acm.hdu.edu.cn/showproblem.php?pid=3113
題意:給出一個正整數n,范圍是[1,1000000],求出滿足方程的一組整數解,要求x最小。
分析:這個方程與平方和不同的是,加號兩邊的任意一個可以為負數,所以直接枚舉然后Hash就顯得不好做了。那么我用一種
比較有效的方式解決。
我們知道,那么我們這樣來做,首先把n的所有因子找出來,枚舉所有的因子。
假設當前的因子為,那么令,即得到:
在這里其實還有一種情況就是:
你會發現這種情況根本沒有解,所以不予考慮。
對上面的方程組消去y,我們得到:?,那么得到:
那么我們就只需要在枚舉因子的過程中,判斷是否為完全平方數和,并且記錄最
小的x以及對應的y。
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include <math.h>using namespace std; const int N = 1000005; const int INF = 1 << 30; const int M = 1005;bool prime[N]; int p[N]; int pri[M],num[M]; int arr[M]; int k,cnt,ct;void isprime() {k = 0;memset(prime,true,sizeof(prime));for(int i=2;i<N;i++){if(prime[i]){p[k++] = i;for(int j=i+i;j<N;j+=i)prime[j] = false;}} }void Divide(int n) {cnt = 0;int t = (int)sqrt(1.0*n);for(int i=0;p[i]<=t;i++){if(n%p[i]==0){int a = 0;pri[cnt] = p[i];while(n%p[i]==0){n /= p[i];a++;}num[cnt] = a;cnt++;}}if(n > 1){pri[cnt] = n;num[cnt] = 1;cnt++;} }void dfs(int dept,int product = 1) {if(dept == cnt){arr[ct++] = product;return;}for(int i=0;i<=num[dept];i++){dfs(dept+1,product);product *= pri[dept];} }void Work(int n) {ct = 0;Divide(n);dfs(0,1);sort(arr,arr+ct);int ctt = 0;int ansx = INF;int ansy = INF;int tmpx = 0;int tmpy = 0;for(int i=0;i<ct;i++){int t = n / arr[i] * 12 - 3 * arr[i] * arr[i];if(t >= 0){int tmp = (int)sqrt(t * 1.0);if(tmp * tmp == t){if((3*arr[i] - tmp)%6==0){ctt++;tmpx = (3*arr[i] - tmp) / 6;if(tmpx < ansx){ansx = tmpx;ansy = arr[i] - tmpx;}}if((3*arr[i] + tmp)%6==0){ctt++;tmpx = (3*arr[i] + tmp) / 6;if(tmpx < ansx){ansx = tmpx;ansy = arr[i] - tmpx;}}}}}if(ctt == 0) puts("Impossible");else printf("%d %d\n",ansx,ansy); }int main() {int n;isprime();while(~scanf("%d",&n)){if(n == 0) break;Work(n);}return 0; }
總結
以上是生活随笔為你收集整理的HDU3113(工科数学分析之分解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: K倍动态减法游戏
- 下一篇: HDU2879(积性函数)