UVa 10125

题目:给你n个数让你在里面找到会不同样的4个数a。b,c。d,使得 d = a + b + c。

分析:数学题,散列表。这是一个优化问题。

            方法1:暴力法;

            先排序,然后直接利用四层循环求解。找到解后直接跳出。也能够以利用二分取代最后一层循环;

            这样的方法,假设遇到特殊的数据就会TLE。

            方法2:分步计算。

            将等式转化为 d - a = b + c。我们分别求解两边的结果,然后找到结果同样的值就可以;

            查找方法。能够使用散列表储存b + c 或 a + b 的值,供还有一边查找;也可存进数组,二分查找。

说明:存储时记录计算的两个元素的下标。每一个数字都不同。注意哈希值可能为负。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

/* Hash define */  
#define nodesize 500000  
#define hashsize 1000  
  
typedef struct node  
{  
    int  value,l,r;  
    node* next;
}list;  
list  dict[nodesize+1];
list* head[hashsize+1];
  
class Hash  
{  
    private:   
        int size;  
    public:  
        Hash(){size = 0;memset( head, 0, sizeof(head) );}  
        int hash( int value ) {return abs(value)%hashsize;}  
        void insert( int value, int i, int j ) {  
            int id = hash(value);  
            dict[size].value = value;  
            dict[size].l = i;
            dict[size].r = j;
            dict[size].next = head[id];
            head[id] = &dict[size ++];  
        }  
        int find( int value, int i, int j ) {  
            int id = hash(value);  
            for ( list* p = head[id] ; p ; p = p->next ) 
                if ( value == p->value )
				if ( i != p->r && i != p->l && j < p->l ) 
					return true;
            return false;
        }  
}; 
/* Hash end */  

int data[1002];

int main()
{
	int n;
	while ( cin >> n && n ) {
		for ( int i = 1 ; i <= n ; ++ i )
			cin >> data[i];
		sort( data+1, data+n+1 );
		
		Hash hash;
		for ( int i = 1 ; i <= n ; ++ i )
		for ( int j = i+1 ; j <= n ; ++ j )
			hash.insert( data[i]+data[j], i, j );
		int flag = 0;
		for ( int i = n ; i >= 1 ; -- i ) {
			for ( int j = 1 ; j <= n ; ++ j )
				if ( i != j && hash.find( data[i]-data[j], i, j ) ) {
					cout << data[i] << endl;
					flag = 1; break;
				}
			if ( flag ) break;
		}
		
		if ( !flag ) cout << "no solution" << endl;
	}
	return 0;
}

原文地址:https://www.cnblogs.com/yjbjingcha/p/7151231.html