代码改变世界

和集

2006-11-08 12:20  老博客哈  阅读(648)  评论(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相差的很多,汗。。。