标签:blog os io for 2014 ar amp log
题目:已知n个数a[1..n],还有另一个数M,在前n个数中找到差值最小的两个数使得他们的和是M。
分析:数学。排序,找M/2。然后向两边分别扩展即可。
设a[s]是第一个大于M/2的数字,
如果M是偶数,并且存在至少两个M/2,则a[s-1]、a[s-2]一定是M/2;
否则a[s-1] <= M/2 ,a[s] > M,从这两点向两边扩展即可(l = s-1,r = s):
若a[l]+a[r] > M,l 向左移动(l --)
若a[l]+a[r] < M,r 向右移动(r ++)
若 a[l]+a[r] = M,则就是解,这是a[l]的a[r]差最小(因为,差值和r与l的插值正相关)。
说明:╮(╯▽╰)╭l --写成了r ++RE好几次。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstdio> using namespace std; int data[10012]; int bs( int r, int key ) { int mid,l = 0; while ( l < r ) { mid = l+(r-l)/2; if ( data[mid] <= key ) l = mid+1; else r = mid; } return r; } int main() { int n,sum; while ( ~scanf("%d",&n) ) { for ( int i = 0 ; i < n ; ++ i ) scanf("%d",&data[i]); data[n] = 1000002; scanf("%d",&sum); sort( data, data+n ); int s = bs( n, sum/2 );//找到第一个大于sum/2的值 if ( s >= 2 && data[s-1]+data[s-2] == sum ) printf("Peter should buy books whose prices are %d and %d.\n\n",data[s-2],data[s-1]); else { int l = s-1,r = s; while ( l >= 0 && r < n ) { if ( data[l]+data[r] == sum ) { printf("Peter should buy books whose prices are %d and %d.\n\n",data[l],data[r]); break; }else if ( data[l]+data[r] < sum ) r ++; else l --; } } } return 0; }
UVa 11057 - Exact Sum,布布扣,bubuko.com
标签:blog os io for 2014 ar amp log
原文地址:http://blog.csdn.net/mobius_strip/article/details/38346079