zoukankan      html  css  js  c++  java
  • 九度 1554:区间问题

    题目描述:

    给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。

    输入:

    输入包含多组测试用例,每组测试用例由一个整数n(1<=n<=10000)开头,代表数组的大小。
    接下去一行为n个整数,描述这个数组,整数绝对值不大于100。
    最后一行为一个整数k(大小在int范围内)。

    输出:

    对于每组测试用例,若存在这个连续区间,输出其开始和结束的位置,s,e(s <= e)。
    若存在多个符合条件的输出,则输出s较小的那个,若仍然存在多个,输出e较小的那个。
    若不存在,直接输出"No"。

    样例输入:
    5
    -1 2 3 -4 9
    5
    3
    -1 2 -3
    7
    2
    -1 1
    0
    样例输出:
    2 3
    No
    1 2

    思路

    1. o(n^n) 复杂度算法超时

    2. 正解. D[i] 记录 0~i 的和, 若 D[j] - D[i] == k, 那么 i~j 是一个可行解. 对 D[i] 进行索引排序后枚举 i 并使用二分查找 j. 时间复杂度为 o(nlogn)

    代码 未通过九度测试

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    
    class Node {
    public:
    	int i, di;
    	Node(int _i, int _di):i(_i), di(_di) {
    
    	}
    	Node() {
    		Node(0, 0);
    	}
    	bool operator<(const Node &ths) const {
    		if(this->di == ths.di)
    			return this->i < ths.i;
    		return this->di < ths.di;
    	}
    };
    
    int d[10010];
    int arr[10010];
    Node nodes[10010];
    
    int st, ed;
    
    
    int binary_search(int low, int high, int target, int &left, int &right) {
    	
    	int low1 = low, high1 = high;
    
    	// find the left part of array
    	while(low1 <= high1) {
    		int mid = (low1+high1)>>1;
    		if(nodes[mid].di < target) {
    			low1 = mid + 1;
    		}else{
    			high1 = mid -1;
    		}
    	}
    	left = low1;
    
    	low1 = low, high1 = high;
    
    	while(low1 <= high1) {
    		int mid = (low1+high1)>>1;
    		if(nodes[mid].di <= target) {
    			low1 = mid + 1;
    		}else{
    			high1 = mid -1;
    		}
    	}
    
    	right = high1;
    
    	if(left < low || right > high || nodes[left].di != target)
    		return -1;
    	return 0;
    }
    
    int main() {
    	freopen("testcase.txt", "r", stdin);
    	int n, k; 
    	while(scanf("%d", &n) != EOF) {
    
    		scanf("%d", arr);
    		nodes[0].i = 0;
    		nodes[0].di = arr[0];
    		d[0] = arr[0];
    		for(int i = 1; i < n; i ++) {
    			scanf("%d", arr+i);
    			d[i] = d[i-1]+arr[i];
    			nodes[i].i = i;
    			nodes[i].di = d[i];
    		}
    
    		scanf("%d", &k);
    		sort(nodes, nodes+n);
    
    		int minst = 0, mined = 0x3f3f3f3f;
    
    		for(int i = 0; i < n; i ++) {
    			int target;
    			if(i == 0) {
    				target = k;
    			}else{
    				target = d[i-1] + k;
    			}
    			
    			int left, right;
    			if(binary_search(0, n-1, target, left, right) == -1) {
    				// didn't find
    				continue;
    			}else {
    				for(int j = left; j <= right; j ++) {
    					int index = nodes[j].i;
    					if(index < i) continue;
    					minst = i;
    					mined = index;
    					break;
    				}
    
    				break;
    			}
    		}
    
    		if(mined != 0x3f3f3f3f)
    			printf("%d %d
    ",minst+1, mined+1 );
    		else
    			printf("No
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3606186.html
Copyright © 2011-2022 走看看