【码蹄集】:监狱

题目描述:

在jojo6的平行宇宙中,空条徐伦在被陷害后获得了15年有期徒刑,对于徐伦来说人生的半辈子需要在监狱中度过了。在【水族馆】监狱中有n个宿舍,第i个宿舍有ai个房间。房间编号从第一个宿舍第一个房间开始,一个宿舍中的房间有一段连续房间编号,如n = 2,a1 = 3,a2 = 5时,房间编号为1到8,编号7的房间是第二个宿舍第四个房间。
小码哥这次想换一种方式拯救徐伦,他想直接去房间中救出徐伦,现在他知道了房间编号,请你告诉他这是第几个宿舍的第几个房间。

格式:

输入格式:第一行是宿舍个数和询问个数n, m。第二行是a1, a2,. . . ,an。第三行是询问序列b1, b2,. . . ,bm
输出格式:对于每个询问,输出一行两个数,表示房间是第几宿舍的第几个房间。

样例:

输入:
3 6
10 15 12
1 9 12 23 26 37
输出:
1 1
1 9
2 2
2 13
3 1
3 12

备注:

在这里插入图片描述

解题思路:

思路挺简单,关键有两点,一个是210会爆int,一个是时间复杂度。爆int直接用long long。关于时间复杂度,如果我们采用最原始的办法,每次查询房间号都逐个减去前面的房间个数,不如开始输入每个宿舍房间数时提前计算好每个宿舍的房间编号区间。例如:三个宿舍,每个宿舍房间个数分别为10,15,12。区间为[0,10],[10,25],[25,37],用数组存储每个区间顶点。问题来了,顺序查找,直接二分。思路直接清晰。

完整代码如下:

#include <bits/stdc++.h>
using namespace std;

int main() 
{
	int n,m;
	long long int x;
	cin>>n>>m;
	long long int a[200005]={0};
	for(int i=1;i<=n;i++){
		cin>>x; 
		if(i==1) a[i]=x;
		else a[i]=x+a[i-1];
	}
	long long int num;
	for(int i=0;i<m;i++){
		cin>>num;
		long long int v=0;
		int left = 0,right = n,mid;
		while(left<right){
			mid = (left+right)/2;
			if(a[mid-1]<num&&num<a[mid]||num==a[mid]){
				break;
			}
			if(a[mid]<num&&num<a[mid+1]||num==a[mid+1]){
				mid++;
				break;
			}
			if(num<a[mid]&&num<a[mid+1])right = mid-1;
			else if(num>a[mid]&&num>a[mid-1])left = mid+1;
		}
		cout<<mid<<" "<<num-a[mid-1]<<endl;
	}
	return 0;
}

你可能感兴趣的:(题解,算法)