uva 1152 二分查找+中途相遇法
2017-07-28 21:44
519 查看
题意:
给定4个n元素集合,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0.问,有多少种说法?
题解:
根据紫书算法,我们计算出a+b的所有和,放入vector数组中,同时计算c+d的所有和,放入vector数组中,之后暴力枚举a+b的所有和,在c+d和数组中二分查找-(a+b),这里需要注意的是原始的二分查找只会找到一个数据,数组中可能会有多个-(a+b),我们需要判断。PE了好几次,uva了格式很严格!
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
vector<LL> sumA,sumB;
int solve(int mid,LL ans)
{
//cout<<mid<<ans<<endl;
int count=0;
int i=mid+1;
int j=mid-1;
while(sumB[i]==ans)
{
count++;
i++;
}
while(sumB[j]==ans)
{
count++;
j--;
}
return count;
}
int main()
{
vector<LL> data[4];
int T;
cin>>T;
LL num,tmp;
while(T--)
{
cin>>num;
for(int i=0;i<num;i++)
{
for(int j=0;j<4;j++)
{
cin>>tmp;
data[j].push_back(tmp);
}
}
LL sum1,sum2;
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
sum1 = data[0][i]+data[1][j];
sum2 = data[2][i]+data[3][j];
sumA.push_back(sum1);
sumB.push_back(sum2);
}
}
LL sizA = sumA.size();
LL sizB = sumB.size();
int ans=0;
sort(sumB.begin(),sumB.end());
for(int i=0;i<sizA;i++)
{
LL se = -sumA[i];
int right=sizB-1;
int left =0;
while(right>=left)
{
int mid = (right+left)>>1;
if(sumB[mid]>se){
right=mid-1;
}
else if(sumB[mid]<se)
{
left=mid+1;
}
else if(sumB[mid]==se){
//cout<<sumB[mid]<<se<<endl;
ans++;
int o=solve(mid,se);
ans+=o;
break;
}
}
}
cout<<ans<<endl;
if(T!=0) cout<<endl;
sumA.clear();
sumB.clear();
for(int j=0;j<4;j++)
{
data[j].clear();
}
}
return 0;
}
给定4个n元素集合,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0.问,有多少种说法?
题解:
根据紫书算法,我们计算出a+b的所有和,放入vector数组中,同时计算c+d的所有和,放入vector数组中,之后暴力枚举a+b的所有和,在c+d和数组中二分查找-(a+b),这里需要注意的是原始的二分查找只会找到一个数据,数组中可能会有多个-(a+b),我们需要判断。PE了好几次,uva了格式很严格!
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
vector<LL> sumA,sumB;
int solve(int mid,LL ans)
{
//cout<<mid<<ans<<endl;
int count=0;
int i=mid+1;
int j=mid-1;
while(sumB[i]==ans)
{
count++;
i++;
}
while(sumB[j]==ans)
{
count++;
j--;
}
return count;
}
int main()
{
vector<LL> data[4];
int T;
cin>>T;
LL num,tmp;
while(T--)
{
cin>>num;
for(int i=0;i<num;i++)
{
for(int j=0;j<4;j++)
{
cin>>tmp;
data[j].push_back(tmp);
}
}
LL sum1,sum2;
for(int i=0;i<num;i++)
{
for(int j=0;j<num;j++)
{
sum1 = data[0][i]+data[1][j];
sum2 = data[2][i]+data[3][j];
sumA.push_back(sum1);
sumB.push_back(sum2);
}
}
LL sizA = sumA.size();
LL sizB = sumB.size();
int ans=0;
sort(sumB.begin(),sumB.end());
for(int i=0;i<sizA;i++)
{
LL se = -sumA[i];
int right=sizB-1;
int left =0;
while(right>=left)
{
int mid = (right+left)>>1;
if(sumB[mid]>se){
right=mid-1;
}
else if(sumB[mid]<se)
{
left=mid+1;
}
else if(sumB[mid]==se){
//cout<<sumB[mid]<<se<<endl;
ans++;
int o=solve(mid,se);
ans+=o;
break;
}
}
}
cout<<ans<<endl;
if(T!=0) cout<<endl;
sumA.clear();
sumB.clear();
for(int j=0;j<4;j++)
{
data[j].clear();
}
}
return 0;
}
相关文章推荐
- UVA 1152 4 Values whose Sum is 0 中途相遇法 二分查找
- UVA - 1152 4 Values whose Sum is 0 【中途相遇法/二分】
- Uva1152 4 Values whose Sum is 0 【中途相遇+二分】【例题8-3】
- UVa1152 4 Values whose Sum is 0 (中途相遇法+二分)
- UVA 1152 4 Values whose Sum is 0 (枚举+中途相遇法)(+Java版)(Java手撕快排+二分)
- Uva1152 查找优化的四种方法 中途相遇法
- uva 1152 4 Values whose Sum is 0(二分_中途相遇|| hash)
- (白书训练计划)UVa 1152 4 Values whose Sum is 0(中途相遇法。。)
- UVA - 1152 4 Values whose Sum is 0问题分解,二分查找
- 8.5-237-uva1152-中途相遇法-二分法
- 中途相遇法,哈希技术(和为0的4个值,uva 1152)
- UVA 1152 --4 Values whose Sum is 0(枚举--中途相遇法)
- uva 1152 和为0的4个值(中途相遇法)
- uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)
- UVa 1152 (中途相遇法) 4 Values whose Sum is 0
- UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
- UVa 1152 - 4 Values whose Sum is 0(中途相遇)
- UVa 1326 - Jurassic Remains(枚举子集+中途相遇法)
- 【二分查找+优化O(n)】【续UVA1121】Subsequence
- Building for UN UVA - 1605 (中途相遇法)