二分寻找解的个数

来源:互联网 发布:网络平台赌博怎么举报 编辑:程序博客网 时间:2024/05/16 10:12

1.HDU1496    Equations

 

Problem Description
Consider equations having the following form:

a*x1^2+b*x2^2+c*x3^2+d*x4^2=0
a, b, c, d are integers from the interval [-50,50] and any of them cannot be 0.

It is consider a solution a system ( x1,x2,x3,x4 ) that verifies the equation, xi is an integer from [-100,100] and xi != 0, any i ∈{1,2,3,4}.

Determine how many solutions satisfy the given equation.
 


 

Input
The input consists of several test cases. Each test case consists of a single line containing the 4 coefficients a, b, c, d, separated by one or more blanks.
End of file.
 


 

Output
For each test case, output a single line containing the number of the solutions.
 


 

Sample Input
1 2 3 -41 1 1 1
 


 

Sample Output
390880

 

先把前两个数的和的所有方案找出 最后二分寻找最后两个数的和

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 10010;int k,a,b,c,d;long long ans;int s[maxn];void init(){    k=0;    for(int i=1;i<=100;i++)        for(int j=1;j<=100;j++)            s[k++]=i*i*a+b*j*j;}void binary_search(int t){    int l=0,r=k;    while(l<r){        int mid=(l+r)/2;        if(s[mid]==t){            ans++;            for(int ss=mid-1;s[ss]==t&&ss>=1;ss--)                if(s[ss]==t)                    ans++;            for(int ss=mid+1;s[ss]==t&&ss<k;ss++)                if(s[ss]==t)                    ans++;            return;        }        if(t>s[mid])            l=mid+1;        else r=mid;    }}int main(){    while(cin>>a>>b>>c>>d){        init();        ans = 0;        if(a>0&&b>0&&c>0&&d>0){            cout<<"0"<<endl;            continue;        }        sort(s,s+k);        for(int i=1;i<=100;i++){            for(int j=1;j<=100;j++){                int t=-(c*i*i+d*j*j);                int l=0,r=k;                binary_search(t);            }        }        printf("%I64d\n",ans*16);    }    return 0;}


UVA1152 4 Values whose Sum is 0

 

Description

Download as PDF

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet(a, b, c, d ) $ \in$A x B x C x D are such thata + b + c + d = 0 . In the following, we assume that all lists have the same sizen .

Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.


The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as228 ) that belong respectively to A, B, C and D .

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.


For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

16-45 22 42 -16-41 -27 56 30-36 53 -37 77-36 30 -75 -4626 -38 -10 62-32 -54 -6 45

Sample Output

5


Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

 

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int a[4010][4];int num1[4001*4001];int num2[4001*4001];int main(){    int cas,n;    scanf("%d",&cas);    while(cas--){        scanf("%d",&n);        for(int i=0;i<n;i++)            for(int j=0;j<4;j++)               scanf("%d",&a[i][j]);        int cnt=0;        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                num1[cnt]=a[i][0]+a[j][1];                num2[cnt]=a[i][2]+a[j][3];                cnt++;            }        }        int count=0;        sort(num1,num1+cnt);        sort(num2,num2+cnt);        for(int i=0;i<cnt;i++){            int l=0,r=cnt-1;            while(l<=r)            {                int mid=(l+r)/2;                if(num1[i]+num2[mid]==0)                {                     for(int j=mid;j>=0&&num2[j]==num2[mid];j--)                         count++;                     for(int j=mid+1;j<cnt&&num2[j]==num2[mid];j++)                         count++;                     break;                }                else if(num1[i]+num2[mid]<0)                    l=mid+1;                else r=mid-1;            }        }        cout<<count<<endl;        if(cas!=0)            puts("");    }    return 0;}

0 0
原创粉丝点击