二进制搜索一个固定点

时间:2015-03-18 11:04:03

标签: c++ stdvector binary-search

我需要编写一个

的程序
  

S = x 1 ,...,x n

一个整数序列,使

  

x 1 &lt; ......&lt; X <子>名词

对于每个整数a和每个索引

  

1≤i≤n

定义

  

f a(i) = x i + a。

给定Sa,告诉我是否有i这样的

  

f a(i) = i。

我已实施以下计划:

#include <iostream>
#include <vector>
using namespace std;

int fixpoint(const vector<int>& v, int a, int esq, int dre) {
  if(esq > dre) return -1;
  int m = (esq+dre)/2;
  if(v[m]+a == m+1) return m+1;
  if(v[m]+a > m+1) return fixpoint(v, a, m+1, dre);
  if(v[m]+a < m+1) return fixpoint(v, a, esq, m-1);


}


int main() {
  int s;
  while(cin >> s) {
    vector<int> v(s);
    for(int i = 0; i<s; ++i) cin >> v[i];
    int n;
    cin >> n;
    for(int i = 0; i<n; ++i) {
      int a;
      cin >> a;
      int fix = fixpoint(v, a, 0, v.size()-1);
      if(fix == -1) cout << "no fixed point for " << a << endl;
      else cout << "fixed point for " << a << ": " << fix << endl;
    }
    cout << endl;
  }
}

程序必须编写满足条件的第一个i,但如果我使用以下输入:

5
-7 -2 0 4 8
1
0

5
0 1 2 3 4
3
0 -1 1

输出结果为:

Sequence #1
no fixed point for 0

Sequence #2
no fixed point for 0
no fixed point for -1
fixed point for 1: 3

第二个序列中1的固定点应为1,因为它是第一个满足条件的i

你能帮帮我吗?

1 个答案:

答案 0 :(得分:0)

我看到两个问题。

首先在你的函数中你应该反转二分搜索的分支,因为f单调递增(如i)如果f > i你必须用较小的i搜索intervall。

int fixpoint(const vector<int>& v, int a, int esq, int dre) {
    if ( esq > dre ) return -1;
    int m = (esq + dre)/2;
    int m1 = m + 1;
    int f = v[m] + a;
    if( f == m1)
        return m1;
    else if( f < m1)
        return fixpoint(v, a, m1, dre);
    else
        return fixpoint(v, a, esq, m-1);
}

其次,你的第二个例子形成不良,每个i f == i。你的函数只返回3,因为它是它检查的第一个索引,3是正确答案为1。