首页 > 代码库 > UVa 11057 - Exact Sum
UVa 11057 - Exact Sum
题目:已知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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。