0
点赞
收藏
分享

微信扫一扫

HDOJ  4334   Trouble


题目:​​http://acm.hdu.edu.cn/showproblem.php?pid=4334​​

题解:

如果我们有两个整数排序的列表A和B,我们可以很容易地找到在线性时间通过保持两个指针如果有一分之一和B在B,这样+ B = c(c给定)。  
现在,对于这个问题,我们创建一个排序的列表s[0]和s[1](称之为M[0]),和一个排序的列表s[2]和s[3](称之为M[1])。
我们可以做到这一点在O(n,log,n ^ 2)。  
然后,对于每个成员c[4]的元素,我们发现如果在M[0]和b在M[1],这样a+b+c=0使用段落中描述的方法之一。以来每个搜索需要O(n ^2)时间(因为大小的列表是O(n ^ 2)),然后我们O(n)的成员在S[4],总时间复杂度算法将O(n ^ 3)。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long int64;
const int N = 200;
int n, t;
int64 S[5][N];
int64 M[2][N*N];
inline int64 sum(int i, int j, int k)
{
return M[0][j] + M[1][k-1] + S[4][i];
}
int main()
{
for(cin >> t; t--; )
{
cin >> n;
int n2 = n * n;
for(int i = 0; i < 5; i ++)
for(int j = 0; j < n; j ++)
cin >> S[i][j];
for(int i = 0; i < 2; i ++)
{
for(int j = 0; j < n; j ++)
for(int k = 0; k < n; k ++)
M[i][j * n + k] = S[i * 2][j] + S[i * 2 + 1][k];
sort(M[i], M[i] + n2);
}
bool result = false;
for(int i = 0; i < n && !result; i ++)
{
int k = n2 - 1;
for(int j = 0; j < n2 && !result; j ++)
{
while(k > 0 && sum(i, j, k-1) > 0)
{
k --;
}
if(sum(i, j, k-1) == 0)
result = true;
}
}
if( result )
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
return 0;
}

举报

相关推荐

0 条评论