2019.09.03贝壳校招(部分题解)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wang907553141/article/details/82388245

这是第一次去试水,好长好长时间没A过题,菜的有点受不了,~~~爆零耻辱下课~~~

题目一

描述

输入n,m;n可以进行 -1,*2操作,
问至少多少次操作才能得到 m 

样例:

输入

4 5

输出

3

思路:
刚开始想复杂了!!!
简单想: 
当n小于m的时候,如果我们想要用最少的操作去接近m,
那么就是尽可能的 *2,如果超过了就减(-1操作)回去,
反过来看,如果 m 为偶数了就让 m 除以 2,
如果为 m 为奇数就,将他凑为偶数,只能是 +1 操作(因为正着是 -1 操作),

#include<cstdio>
#include<algorithm>

using namespace std;

int n, m;

int main() {
	while(~scanf("%d%d", &n, &m)) {
		if(n >= m) {
			printf("%d\n", n-m);
		}
		int ans = 0;
		while(m > n) {
			if(m & 1) {	
				m++;
				ans++;	
			}
			m >>= 1;
			ans++;
		}
		printf("%d\n", ans+n-m);
	}
	return 0;
}

题目二

描述

Vasya很喜欢排多米诺骨牌。他已经厌倦了普通的多米诺骨牌,所以他用不同高度的多米诺骨牌。他从左边到右边,把n个多米诺骨牌沿一个轴放在桌子上。每一个多米诺骨牌垂直于该轴,使该轴穿过其底部的中心。第i个多米诺骨牌具有坐标xi与高度hi。现在Vasya想要知道,对于每一个多米诺骨牌如果他推倒的话,右侧会有多少个多米诺骨牌也会倒下。

想想看,一个多米诺倒下,如果它严格的触动右侧的多米诺骨牌,被触碰的也会倒下。换句话说,如果多米诺骨牌(初始坐标x和高度h)倒下,会导致所有在[ X + 1,x + H - 1]范围内的多米诺骨牌倒下。

Input

输入有多组测试数据,处理到文件结尾。

每组测试数据第一行包含整数n(1≤N≤10^5),这是多米诺骨牌的数量。然后n行,每行包含两个整数xi与hi(-10^8≤xi≤10^8 ,2 ≤hi≤108),xi表示多米诺骨牌的坐标和hi表示多米诺骨牌的高度。没有两个多米诺骨牌在同一个坐标点上。

Output

对于每组数据输出一行,包含n个空格分隔的数Zi - 表示倒下的多米诺骨牌数量,如果Vasya推第i个多米诺骨牌(包括多米诺骨牌本身)。

Sample Input

4

16 5

20 5

10 10

18 2

Sample Output

3

1

4

1

思路:看过有人说dp,dp应该是标程;~~不会dp~~

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int n;
struct node {
	int x;  // 牌的坐标 
	int h;  // 牌的高度 
	int mx;  // 牌倒下后的能到达的最远位置 
	int index;  // 牌的索引 
	int cnt;  // 此牌能压倒的牌的数量 
}a[100010];

bool cmp1(node p, node q) {
	return p.x < q.x;
}

bool cmp2(node p, node q) {
	return p.index < q.index;
}

int main() {
	while(~scanf("%d", &n)) {
		memset(a, 0, sizeof(a));
		for(int i=0; i<n; i++) {
			scanf("%d%d", &a[i].x, &a[i].h);
			a[i].mx = a[i].x + a[i].h; 
			a[i].index = i;
			a[i].cnt = 1; 
		}
		// 按起始坐标位置排序 
		sort(a, a+n, cmp1);
		for(int i=n-2; i>=0; i--) {
			int j = i + 1;
			int mmx = a[i].mx;
			while(j < n && mmx > a[j].x) {
				// 累计能压倒的牌的数量 
				a[i].cnt += a[j].cnt;
				mmx = max(mmx, a[j].mx);
				// 跳过能压倒的中间的牌 
				j += a[j].cnt;
			}
			// 更新第i-1块牌的能到达的最远位置,防止之后重复统计中间位置的牌 
			a[i].mx = mmx; 
		}
		// 按起始索引排序,回到最初的位置 
		sort(a, a+n, cmp2);
		for(int i=0; i<n; i++) {
			printf("%d\n", a[i].cnt);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wang907553141/article/details/82388245