UVa 10125 - Sumsets

来源:互联网 发布:外套淘宝详情页 编辑:程序博客网 时间:2024/05/19 02:26

题目:给你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;}

0 0
原创粉丝点击