Help cupid
Problem's Link:
Mean:
地球被划分为24个时区(-11~23),现在给出n个人的时区,将这n个人两两配对,使得n/2对配偶的时区差值之和最小。
analyse:
由于给的都是整数,而且只有24个时区,首先统计每个时区有多少人。
然后每个时区的人数都%2,因为同一时区的两个人差值为0。
接着就是枚举人数不为零的时区的人数。
根据贪心的思想,我们知道除了第一个和最后一个外,其他人都是和相邻两个的其中一个匹配,为什么呢?自己画个圈去证明。
对于第一个和最后一个,要么最后特判一下,要么直接在数组后面接一个每个元素+24的数组(处理环常用方法),暴力一下就行。
Time complexity: O(N)
Source code:
/* * this code is made by crazyacking * Verdict: Accepted * Submission Date: 2015-07-26-08.27 * Time: 0MS * Memory: 137KB */ #include <queue> #include <cstdio> #include <set> #include <string> #include <stack> #include <cmath> #include <climits> #include <map> #include <cstdlib> #include <iostream> #include <vector> #include <algorithm> #include <cstring> #define LL __int64 #define ULL unsigned long long using namespace std; int a [ 50 ], ti [ 50 ]; int main() { ios_base :: sync_with_stdio( false); cin . tie( 0); int n , tmp; while( cin >>n) { memset( a , 0 , sizeof a); for( int i = 0; i <n; ++ i) { cin >> tmp; a [ tmp + 11 ] ++; } for( int i = 0; i < 50; ++ i) a [ i ] &= 1; int cnt = 0; for( int i = 0; i < 50; ++ i) { if( a [ i ]) ti [ cnt ++ ] = i; } int c = cnt; for( int i = 0; i < c; ++ i) ti [ cnt ++ ] = ti [ i ] + 24; LL ans = LLONG_MAX; for( int i = 0; i < c; ++ i) { LL sum = 0; for( int j = 0; j < c; j += 2) sum += ti [ i + j + 1 ] - ti [ i + j ]; ans = ans < sum ? ans: sum; } if( ans == LLONG_MAX) cout << 0 << endl; else cout << ans << endl; } return 0; } /* */