【九度】题目1554:区间问题 map<int , vector<int> >的使用
转自:http://blog.csdn.net/u013491262/article/details/21406351
题目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
记录前缀和 sum[i] = x[1] + x[2] + .... + x[i]
查找 x[s] + x[s+1] + ....+ s[e] = k ;
算法:
从小到大 固定 s ,查找e 。
=> 固定s , 在sum[s+1] , sum[s+2] ,....sum[n]内查找sum[最小的e] = k+sum[s-1] 。
做映射: sum[i] -> i 。
注意sum[i]会有重复,这个时候做 整数 -> 链表 的映射。 每次查找logN。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 const int Max_N = 10008 ; 2 3 int x[Max_N] ; 4 5 int sum[Max_N] ; 6 7 int n , k ; 8 9 map<int , vector<int> > st ; 10 11 12 13 int getint(){ 14 15 int t=0,flag=1; 16 17 char c=getchar(); 18 19 while(c<'0'||c>'9'||c=='-'){ 20 21 if(c=='-') 22 23 flag=-1 ; 24 25 c=getchar(); 26 27 } 28 29 while(c>='0'&&c<='9'){ 30 31 t=t*10+c-'0'; 32 33 c=getchar(); 34 35 } 36 37 return t*flag; 38 39 } 40 41 42 43 44 45 46 47 void Ans(){ 48 49 int start , nowserch ; 50 51 vector<int> now ; 52 53 vector<int> ::iterator it ; 54 55 for(start = 1 ; start <= n ; start++){ 56 57 nowserch = sum[start-1] + k ; 58 59 if(st.find(nowserch) == st.end()) 60 61 continue ; 62 63 now = st[nowserch] ; 64 65 for(it = now.begin() ; it < now.end() ; it++){ 66 67 if((*it) >= start){ 68 69 printf("%d %d\n" , start , (*it)) ; 70 71 return ; 72 73 } 74 75 } 76 77 } 78 79 puts("No") ; 80 81 return ; 82 83 } 84 85 86 87 int main(){ 88 89 int i ; 90 91 while(scanf("%d" ,&n) != EOF){ 92 93 st.clear() ; 94 95 sum[0] = 0 ; 96 97 for(i = 1 ; i <= n ; i++){ 98 99 x[i] = getint() ; 100 101 sum[i] = sum[i-1] + x[i] ; 102 103 st[sum[i]].push_back(i) ; 104 105 } 106 107 scanf("%d" ,&k) ; 108 109 Ans() ; 110 111 } 112 113 return 0 ; 114 115 } 116 117