例题1:
1,这题第一思想其实就是用枚举,但是这个题目的数据规模太大了,所以肯定不能否则复杂度会达到百亿,这种规模一般来说在所有的程序设计竞赛中是肯定过不了的。但是这个思维也说一下把,其实就是用两次循环,分开来遍历,如果相加为m的话,就ok了。
2,其实就是先对数组进行排序。先找到一个数,剩下一个数就是m-a[i],这个数用二分查找在这个数组中找。
3,这种解法是把i指向头,j指向尾。把a[i]+a[j]与m进行比较,如果m大的话,就把i++,如果小的话就把j++。
例题2:
题目描述 : 农夫john建造了一座很长的畜栏,它包括N(2<=N<=100000)个隔间,这些小隔间的位置为x0,…,xn-1(0<=xi<=1000000000,均为整数,各不相同)。
john的C(2<=C<=N)头牛每头分到一个隔间。牛都希望互相离得远点省得互相打扰。怎样才能使任意两头牛之间的最小距离尽可能的大,这个最大的最小距离是多少呢?
思路与想法:
这题第一个想法肯定是用暴搜啊,但是一看n的规模心凉了半截,估计没戏了。还有一个想法就是尽可能大,emmm能不能用贪心找到局部最优解呢?我感觉应该有戏但是没认真思考(懒死了)。
暴搜的思维:首先只要能够在这个D下可以把所有的牛都放到隔间里面就ok了。首先隔间之间最大距离是1000000000/C。从1000000000/C到1进行枚举,所找到的第一个D满足题意的就是题目的解。
尝试的方法:首先把第一条牛放在x0位置,第k个牛放在xi,第k+1条牛放在(xj+D,1000000)之间。如果找不到的话就把D--。再次尝试。如果所有的牛都能放得下的话就是了。当时这样的话都到100亿了肯定不行啊。所以这题用二分的思维。
#include <iostream> using namespace std; int n; int c; cowstall = [100000000]; bool isok(int d){ int cnt = 1;//注意第一个位置有一条牛 temp = cowstall[0]; for(int i = 0;i<n;i++){ if(cowstall[i] - temp > d){ cnt++; tempstall = cowstall[i]; //一定要记住上一条牛的位置。 } } if(cnt>=c){ return true; }else{ return false; } } int main(){ cin>>n>>c; for(int i = 0;i<N;i++){ cin>>cowstall[i]; } int left = 0; //注意这个right是坐标值不是位置 int right = cowstall[n-1] - cowstall[0]; while(left<right){ int mid = left+(right-left)/2; if(isok(mid)){ left = mid+1; }else{ right = mid; } } }
这个代码自己写还真不是那么容易写出来,注意一下什么是坐标体会一下枚举和二分的思维和思想。如何一步步简化代码。
因最近自己在学python所以附上网络上看来的python代码:
N = (int)(input()) C = (int)(input()) cow_stall = [] for i in range(N): cow_stall.append((int)(input())) cow_stall.sort() def isok(distance): count = 1 tempStall = cow_stall[0] for i in range(1,N): if(cow_stall[i]-tempStall>=distance): count += 1 tempStall = cow_stall[i] if(count>=C): return True else: return False def SearchMaxD(): left = 0 right = cow_stall[-1]-cow_stall[0] while(left<right): mid = (int)((left+right)/2) if(isok(mid)): left = mid+1 else: right = mid print(mid) SearchMaxD() 原文链接:https://blog.csdn.net/matafeiyanll/article/details/104862345