問題の意味:
ZJMは、4つの列A、B、C、Dを有し、各列は、桁数を有するN。ZJMそれぞれの列番号から取られた数が、彼はそのような4と0の数、そのプログラムのどのように多くの種類を知っていただきたいと思います。
場合は、列の数が異なる数として扱うために、数字の同じ複数有しています。
彼を助けてください!
入力:
最初の行:N(列の数の数を表す)(1≤n≤4000)
次のn行目、4つの数字のi番目の行、列A、B、C、Dの各数i番目の桁(以下28の力に桁2)
出力:
異なる組み合わせの数の出力。
入力サンプル:
6
-45 22 42 -16である
-41 -27 56 30である
-36 53 77 -37である
-36 30 -75 -46
26 62である-38 -10
-32 -54 -6 45
サンプル出力:
5
サンプル説明:
(-45、-27、42、30)、(26、30、-10、-46)、(-32、22、56、-46)、( - 32、30、-75、77)、( - 32、-54、56、30)
アイデア:
直接4つのネストされたループによる場合には、時間の複雑さが大きすぎるので、他の方法の使用。和は、2つの系列を取得し、そして容器、容器と、この種のために格納されている数値で2つの入れ子ループ。また、2つの入れ子ループ付加価値の2つの系列によって引き出され、最初と最後の列の位置及び二つの対向する前面を見つけ、2つの関数の数、得られた最終的な結果によります。2つのルックアップ機能では、アプリケーションがコンテナに0から必要な容器の容量値を見つけるために見つけるために、位置を見つけるために検索バイナリー。
コード:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> temp;
int find1(int am)
{
am=-am;
int l=0;
int r=temp.size();
int count=-1;
while(l<=r)
{
int mid=(l+r)/2;
if(temp[mid]==am)
{
count=mid;
r=mid-1;
}
else if(temp[mid]>am)
{
r=mid-1;
}
else
{
l=mid+1;
}
}
return count;
}
int find2(int am)
{
am=-am;
int l=0;
int r=temp.size();
int count=-1;
while(l<=r)
{
int mid=(l+r)/2;
if(temp[mid]==am)
{
count=mid;
l=mid+1;
}
else if(temp[mid]>am)
{
r=mid-1;
}
else
{
l=mid+1;
}
}
return count;
}
int main()
{
int n;
cin>>n;
int count=0;
//int a1,a2;
int a[n],b[n],c[n],d[n];
for(int i=0;i<n;i++)
{
cin>>a[i]>>b[i]>>c[i]>>d[i];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
temp.push_back(a[i]+b[j]);
//a1=a[i]+b[j];
}
}
sort(temp.begin(),temp.end());
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int am=c[i]+d[j];
int num1=find1(am);
int num2=find2(am);
if(num1!=-1&&num2!=-1)
count=count+num2-num1+1;
}
}
cout<<count;
return 0;
}