思路

参考算法笔记

  1. 枚举左端点,再找到第一个值为sum[i-1]+m的——这一步必须要用二分查找,不然会超时几个测试点
  2. 如果不存在,由于二分查找的结果是第一个大于等于m的值,因此结果比大于等于m,不等于m的话那么大于m,把这个值求出来
  3. 遍历一遍数组,一边遍历一边找符合条件的值

代码

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<vector>
  4. using namespace std;
  5. const int N = 100010;
  6. vector<int> sum(N);
  7. int n, m,nearM = 1000000000;
  8. int upper_bound(int L, int R, int x){
  9. int left = L, right = R, mid;
  10. while(left < right){
  11. mid = left + (right - left)/2;
  12. if(sum[mid]<=x) left = mid+1;
  13. else right = mid;
  14. }
  15. return left;
  16. }
  17. int main(){
  18. scanf("%d%d",&n,&m);
  19. sum[0] = 0;
  20. for(int i = 1; i <= n; i++){
  21. scanf("%d",&sum[i]);
  22. sum[i] += sum[i-1];
  23. }
  24. for(int i = 1; i <= n; i++){
  25. int j = upper_bound(i, n + 1, sum[i-1] + m);
  26. if(sum[j-1] - sum[i-1]==m){//这里j要-1
  27. nearM = m;
  28. break;
  29. } else if(j <= n&&sum[j] - sum[i - 1] < nearM){//这个一定是大于m的
  30. nearM = sum[j] - sum[i - 1];
  31. }
  32. }
  33. for(int i = 1; i <= n; i++){
  34. int j = upper_bound(i, n + 1, sum[i - 1] + nearM);
  35. if(sum[j - 1] - sum[i - 1] == nearM){
  36. printf("%d-%d\n",i,j-1);
  37. }
  38. }
  39. return 0;
  40. }

自己写的复杂度是O(n^2)级的,有三个测试点超时了

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<vector>
  4. using namespace std;
  5. int main(){
  6. int n, m;
  7. scanf("%d%d", &n, &m);
  8. vector<int> input(n+1),sum(n+1);
  9. vector<int> left, right;
  10. sum[0] = 0, input[0] = 0;
  11. for(int i = 1; i <= n; i++){
  12. scanf("%d", &input[i]);
  13. sum[i] = sum[i-1] + input[i];
  14. }
  15. for(int i = 1; i<= n; i++){
  16. for(int j = i; j <= n; j++){
  17. if(sum[j]-sum[i-1]==m){//第i个到第j个的和
  18. left.push_back(i);
  19. right.push_back(j);
  20. }
  21. }
  22. }
  23. int len = left.size();
  24. if(len == 0){//没有数字加入,找第一个大于m的和
  25. int temp = m;
  26. m = 1000000000;
  27. for(int i = 1; i<= n; i++){
  28. for(int j = i; j <= n; j++){
  29. if(sum[j]-sum[i-1]<m&&sum[j]-sum[i-1]>temp){//第i个到第j个的和
  30. m = sum[j]-sum[i-1];
  31. break;
  32. }
  33. }
  34. }
  35. //再找一次
  36. for(int i = 1; i<= n; i++){
  37. for(int j = i; j <= n; j++){
  38. if(sum[j]-sum[i-1]==m){//第i个到第j个的和
  39. left.push_back(i);
  40. right.push_back(j);
  41. }
  42. }
  43. }
  44. }
  45. len = left.size();
  46. for(int i = 0; i < len; i++){
  47. printf("%d-%d\n",left[i],right[i]);
  48. }
  49. }