poj 2549 折半枚举+二分

三重循环肯定TLE,所以采用“折半枚举”的方法+二分查找来提高速度,不同的是需要保存两个下标用来判定是否有重复元素。

 1 #include <algorithm>

 2 #include <iostream>

 3 #include <cstring>

 4 #include <cstdio>

 5 using namespace std;

 6 

 7 const int N = 1000;

 8 int a[N];

 9 int n, cnt;

10 

11 struct Node

12 {

13     int ai, aj, v;

14     bool operator < ( const Node & o ) const

15     {

16         return v < o.v;

17     }

18 } node[N * N];

19 

20 void solve()

21 {

22     for ( int i = n - 1; i > 0; i-- )

23     {

24         for ( int j = i - 1; j >= 0; j-- )

25         {

26             Node tmp;

27             tmp.v = a[i] - a[j];

28             int pos = lower_bound( node, node + cnt, tmp ) - node;

29             while ( node[pos].v == tmp.v )

30             {

31                 if ( node[pos].ai != a[i] && node[pos].ai != a[j]

32                   && node[pos].aj != a[i] && node[pos].aj != a[j] )

33                 {

34                     printf("%d\n", a[i]);

35                     return ;

36                 }

37                 pos++;

38             }

39         }

40     }

41     printf("no solution\n");

42 }

43 

44 int main ()

45 {

46     while ( scanf("%d", &n) != EOF )

47     {

48         if ( n == 0 ) break;

49         cnt = 0;

50         for ( int i = 0; i < n; i++ )

51         {

52             scanf("%d", a + i);

53             for ( int j = i - 1; j >= 0; j-- )

54             {

55                 node[cnt].ai = a[i];

56                 node[cnt].aj = a[j];

57                 node[cnt].v = a[i] + a[j];

58                 cnt++;

59             }

60         }

61         sort( node, node + cnt );

62         node[cnt].v = 999999999;

63         sort( a, a + n );

64         solve();

65     }

66     return 0;

67 }

 

你可能感兴趣的:(poj)