和集
2006-11-08 12:20 老博客哈 阅读(651) 评论(0) 编辑 收藏 举报/*
http://acm.hnu.cn:8080/online/?action=problem&type=show&id=10181
*/
#include <cstdio>
#include <cstdlib>
using namespace std;
struct s
{
int a; //前一个操作数的下标
int b; //后一个操作数的下标
int value; //存储操作后的值
};
int n;
s sub1[499501];
s sub2[499501];
int data[1001];
int num = 0;
int comp(const void* aa, const void* bb) {
struct s* a= (s*)aa;
struct s* b = (s*)bb;
return a->value - b->value;
}
int FindSub2(int start, int end, int value)
{
int left = start;
int right = end - 1;
int mid;
while( left <= right )
{
mid = (left + right) / 2;
if( sub2[mid].value == value )
return mid;
else if( sub2[mid].value > value )
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
void ReadInfo()
{
for(int i = 0; i < n; i++)
{
scanf("%d",&data[i]);
}
}
//存储+, -的值
void StoreValue()
{
int i, j;
num = 0;
for(i = 0; i < n; i++)
{
for(j = i + 1; j < n; j++)
{
sub1[num].a = i;
sub1[num].b = j;
sub1[num].value = data[i] + data[j];
int tmpi, tmpj;
if(data[i] > data[j])
tmpi = i, tmpj = j;
else
tmpi = j, tmpj = i;
sub2[num].a = tmpi;
sub2[num].b = tmpj;
sub2[num].value = data[tmpi] - data[tmpj];
num++;
}
}
}
int FindD()
{
int i, j;
int max = -0x7FFFFFFF;
qsort(sub1,num,sizeof(struct s),comp);
qsort(sub2, num, sizeof(struct s),comp);
int start = 0;
for(i = 0; i < num; i++)
{
while(start < num && sub2[start].value < sub1[i].value)
start++;
if(start >= num)
break;
int index = FindSub2(start, num, sub1[i].value);
if(index == -1)
continue;
if(sub2[index].a == sub1[i].a || sub2[index].a == sub1[i].b
|| sub2[index].b == sub1[i].a ||sub2[index].b == sub1[i].b)
continue;
if(max < data[ sub2[index].a ])
max = data[ sub2[index].a ];
}
return max;
}
int main()
{
int i, j;
while( scanf("%d",&n) != EOF && n)
{
ReadInfo();
StoreValue();
int d = FindD();
if( d == -0x7FFFFFFF )
printf( "no solution\n");
else
printf("%d\n",d);
}
return 0;
}
我是这样做的,存储所有的和和差的情况(差只取正值), 然后遍历和,用二分去查找差中是否存在和。http://acm.hnu.cn:8080/online/?action=problem&type=show&id=10181
*/
#include <cstdio>
#include <cstdlib>
using namespace std;
struct s
{
int a; //前一个操作数的下标
int b; //后一个操作数的下标
int value; //存储操作后的值
};
int n;
s sub1[499501];
s sub2[499501];
int data[1001];
int num = 0;
int comp(const void* aa, const void* bb) {
struct s* a= (s*)aa;
struct s* b = (s*)bb;
return a->value - b->value;
}
int FindSub2(int start, int end, int value)
{
int left = start;
int right = end - 1;
int mid;
while( left <= right )
{
mid = (left + right) / 2;
if( sub2[mid].value == value )
return mid;
else if( sub2[mid].value > value )
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
void ReadInfo()
{
for(int i = 0; i < n; i++)
{
scanf("%d",&data[i]);
}
}
//存储+, -的值
void StoreValue()
{
int i, j;
num = 0;
for(i = 0; i < n; i++)
{
for(j = i + 1; j < n; j++)
{
sub1[num].a = i;
sub1[num].b = j;
sub1[num].value = data[i] + data[j];
int tmpi, tmpj;
if(data[i] > data[j])
tmpi = i, tmpj = j;
else
tmpi = j, tmpj = i;
sub2[num].a = tmpi;
sub2[num].b = tmpj;
sub2[num].value = data[tmpi] - data[tmpj];
num++;
}
}
}
int FindD()
{
int i, j;
int max = -0x7FFFFFFF;
qsort(sub1,num,sizeof(struct s),comp);
qsort(sub2, num, sizeof(struct s),comp);
int start = 0;
for(i = 0; i < num; i++)
{
while(start < num && sub2[start].value < sub1[i].value)
start++;
if(start >= num)
break;
int index = FindSub2(start, num, sub1[i].value);
if(index == -1)
continue;
if(sub2[index].a == sub1[i].a || sub2[index].a == sub1[i].b
|| sub2[index].b == sub1[i].a ||sub2[index].b == sub1[i].b)
continue;
if(max < data[ sub2[index].a ])
max = data[ sub2[index].a ];
}
return max;
}
int main()
{
int i, j;
while( scanf("%d",&n) != EOF && n)
{
ReadInfo();
StoreValue();
int d = FindD();
if( d == -0x7FFFFFFF )
printf( "no solution\n");
else
printf("%d\n",d);
}
return 0;
}
刚开始使用的是lower_bound,目测大约有10秒以上,自己写了一个二分,一下快多了。听kaikai说,STL在debug和release相差的很多,汗。。。