6 条题解

  • 1
    @ 2024-4-9 16:17:23

    万能二分板子,找左右边界即可 PS:记得注意下标嗷

    #include <bits/stdc++.h>
    #define endl '\n'
    #define int long long 
    #define INF 0x3f3f3f3f3f
    const int N = 100010;
    using namespace std;
    int arr[N];
    int n,q,tmp;
    int bs_left(int arr[],int n,int x){
    	int l = 0;
    	int r = n+1;
    	while(l+1<r){
    		int mid = (l+r)/2;
    		if(arr[mid]<x){
    			l = mid;
    		}else{
    			r = mid;
    		}
    	}
    	if(arr[r] == x){
    		return r-1;
    	}else{
    		return -1;
    	}
    }
    
    int bs_right(int arr[],int n,int x){
    	int l = 0;
    	int r = n+1;
    	while(l+1<r){
    		int mid = (l+r)/2;
    		if(arr[mid]<=x){
    			l = mid;
    		}else{
    			r = mid;
    		}
    	}
    	if(arr[l] == x){
    		return l-1;
    	}else{
    		return -1;
    	}
    }
    signed main()
    {
    	std::ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    	cin>>n>>q;
    	for(int i = 1; i<= n;i++){
    		cin>>arr[i];
    	}
    	while(q--){
    		cin>>tmp;
    		int ans_left = bs_left(arr,n,tmp);
    		int ans_right = bs_right(arr,n,tmp);
    		cout<<ans_left<<" "<<ans_right<<endl;
    	}
    	return 0;
    }
    
    • 0
      @ 2024-4-20 12:33:48

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

      pair<int, int> findRange(const vector<int>& arr, int target) { int n = arr.size(); int left = -1, right = -1;

      // 寻找起始位置
      int low = 0, high = n - 1;
      while (low <= high) {
          int mid = low + (high - low) / 2;
          if (arr[mid] < target) {
              low = mid + 1;
          } else if (arr[mid] > target) {
              high = mid - 1;
          } else {
              left = mid;
              high = mid - 1; // 继续寻找左边界
          }
      }
      
      // 寻找终止位置
      low = 0, high = n - 1;
      while (low <= high) {
          int mid = low + (high - low) / 2;
          if (arr[mid] < target) {
              low = mid + 1;
          } else if (arr[mid] > target) {
              high = mid - 1;
          } else {
              right = mid;
              low = mid + 1; // 继续寻找右边界
          }
      }
      
      return {left, right};
      

      }

      int main() { int n, q; cin >> n >> q;

      vector<int> arr(n);
      for (int i = 0; i < n; ++i) {
          cin >> arr[i];
      }
      
      for (int i = 0; i < q; ++i) {
          int target;
          cin >> target;
          pair<int, int> result = findRange(arr, target);
          cout << result.first << " " << result.second << endl;
      }
      
      return 0;
      

      }

      • 0
        @ 2024-4-12 19:54:21
        #include <bits/stdc++.h>
        using namespace std;
        #define endl "\n"
        typedef long long ll;
        
        int main()
        {
            ios::sync_with_stdio(false);
            cin.tie(0);
            cout.tie(0);
        
            ll n, q;
            cin >> n;
            cin >> q;
        
            vector<ll> q_arr(q);
            vector<ll> a(n);
        
            ll index_begin, index_end;
            for (int i = 0; i < n; ++i)
            {
                cin >> a[i];
            }
            for (int i = 0; i < q; ++i)
            {
                cin >> q_arr[i];
            }
        
            for (ll q_i : q_arr)
            {
                
                auto it_l = lower_bound(a.begin(), a.end(), q_i);
                if (it_l == a.end() or (*it_l != q_i))
                {
                    printf("-1 -1\n");
                }
                else
                {
                    index_begin = distance(a.begin(), it_l);
                    index_end = distance(a.begin(), upper_bound(it_l, a.end(), q_i))-1;
                    printf("%lld %lld\n", index_begin, index_end);
                }
            }
        
            return 0;
        }
        
        • 0
          @ 2024-4-11 15:41:29

          用python做的,前面一部分判断在最左边和最右边的情况,然后分析不在边界的情况,用二分法找到其中一个值的时候,再用循环分别向前找和向后找并记录位置

          n,q = map(int,input().split())
          num_list = list(map(int,input().split()))
          quest_list=[]
          def check(num):
              global num_list
              begin = 0
              end = len(num_list) - 1
              pos_begin = 0
              pos_end = 0
              flag = True
              if num_list[begin] == num:
                  flag = False
                  count = 0
                  pos_begin = 0
                  while (num_list[count] == num):
                      pos_end = count
                      count += 1
              elif num_list[end] == num:
                  flag = False
                  count = len(num_list) - 1
                  pos_end = len(num_list) - 1
                  while (num_list[count] == num):
                      pos_begin = count
                      count -= 1
              else:
                  while((end - begin) != 1):
                      middle = (begin + end) // 2
                      if num > num_list[middle]:
                          begin = middle
                      elif num <num_list[middle]:
                          end = middle
                      else:
                          flag = False
                          count1 = middle
                          count2 = middle
                          while(num_list[count1] == num):
                              pos_begin = count1
                              count1 -= 1
                          while(num_list[count2] == num):
                              pos_end = count2
                              count2 += 1
                          break
              if flag:
                  pos_begin = -1
                  pos_end = -1
              print(pos_begin,pos_end)
          
          for i in range(q):
              quest_list.append(int(input()))
          for quest_num in quest_list:
              check(quest_num)
          
          • 0
            @ 2024-4-10 22:55:37

            Python调库

            import sys
            import bisect
            input = sys.stdin.readline
            
            n, q = map(int, input().split())
            d = list(map(int, input().split()))
            for _ in range(q):
                num = int(input())
                if num < d[0] or num > d[-1]:
                    print(-1, -1)
                    continue 
                left = bisect.bisect_left(d, num)
                if d[left] != num:
                    print(-1,-1)
                    continue
                right = min(bisect.bisect_right(d, num), n-1)
                if d[right] != num:
                    right-=1
                print(left,right)
            
            • 0
              @ 2024-4-10 20:16:51

              一种全新的思路来解决二分问题

              不需要仔细思考边界问题

              #include<iostream>
              #include<algorithm>
              #include<cmath>
              #include<cstdio>
              #include<cstring>
              #include<string>
              using namespace std;
              int n,q;
              
              const int N=100010;
              int nums[N];
              int front_find(int target){
              	int l=-1,r=n;
              	while(l+1!=r){
              		int mid=l+r>>1;
              		if(nums[mid]<target) l=mid;
              		else r=mid;
              	}
              	if(r==n || nums[r]!=target) return -1;
              	else return r;
              }
              int end_fond(int target){
              	int l=-1,r=n;
              	while(l+1!=r){
              		int mid=l+r>>1;
              		if(nums[mid]>target) r=mid;
              		else l=mid;
              	}
              	if(l==-1 || nums[l]!=target) return -1;
              	else return l;
              }
              void slove(){
              	int target;
              	cin>>target;
              	int l=front_find(target);
              	if(l!=-1){
              		int r=end_fond(target);
              		cout<<l<<" "<<r<<endl;
              	}
              	else cout<<"-1 -1"<<endl;
              	
              }
              int main(){
              	cin>>n>>q;
              	for(int i=0;i<n;i++) scanf("%d",&nums[i]);
              	while(q--) slove();
              
              	return 0;
              }
              
              • 1

              信息

              ID
              88
              时间
              1000ms
              内存
              256MiB
              难度
              7
              标签
              递交数
              656
              已通过
              150
              上传者