Four columns

Title: four columns
that Italy: ZJM has four columns A, B, C, D, each column has the number of digits n. ZJM a number taken from each respective column number, he would like to know how many kinds of programs such that the number of 4 and 0.
When a number of columns has the same plurality of numbers, to treat them as a different number.
Please help him!

Input:
First line: n (the number represents the number of digits in columns) (1≤n≤4000)
the next n-th row, the i-th row of four numbers, each number of columns A, B, C, D of the i-th digit (digit 2 to the power of not more than 28)

Output:
Output of the number of different combinations.

Example:
Here Insert Picture Description

Problem-solving ideas: First, think about violence, O (n4) direct violence, then the timeout (manual funny). Then optimization, we can, first A, B, and ended up then calculated and sorted in an array, so that the time complexity is O (N2 logn2). Then seek out C + D, followed by two minutes or O (N2 logn2), to find the C + D opposite of the position of the A + B is, if there is even a result, such use half the time complexity of n2 * logn of ,This is acceptable.

Code:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int a[4][4005];
vector<int> h,z;
int main()
{
    int n,x;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<4;j++)
        {
            cin>>x;
            a[j][i]=x;
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            h.push_back(a[0][i]+a[1][j]);
        }
    }
    sort(h.begin(),h.end());//A+B排序
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            z.push_back(a[2][i]+a[3][j]);
        }
    }//C+D不用排序
    int total=0;
    for(int i=0;i<z.size();i++)
    {
        z[i]=-z[i];
        int l=0,r=h.size()-1;
        int ans=-1;
        while(l<=r)//找相反数二分
        {
            int mid=(l+r)/2;
            if(h[mid]>z[i])
            {
                r=mid-1;
            }else if(h[mid]<z[i])
            {
                l=mid+1;
            }else if(h[mid]==z[i])
            {
                ans=mid;
                l=mid+1;
            }
        }
        if(ans==-1)//没找到,白给
        {
            continue;
        }
        if(h[ans]==z[i])
        {
            total++;//找到
            for(int j=ans-1;j>=0;j--)//在这个数周围找找看有没有相同的
            {
                if(h[j]==z[i])
                {
                    total++;
                }else
                {
                    break;
                }
            }
            for(int j=ans+1;j<h.size();j++)
            {
                if(h[j]==z[i])
                {
                    total++;
                }else
                {
                    break;
                }
            }
        }
    }
    cout<<total<<endl;
}
Published 15 original articles · won praise 0 · Views 225

Guess you like

Origin blog.csdn.net/qq_43653717/article/details/104858205