百度24届暑期实习招聘Web前端工程师(3月13日场)

题目1

小红拿到了一个字符串,她想知道这个字符串能否通过重新排列组成"Baidu"字符串?
注:必须大小写完全相同。
共有t组询问。

输入描述

第一行输入一个正整数t,代表询问次数。
接下来的t行,每行输入一个仅包含英文字母的字符串。所有字符串的长度之和保证不超过200000。

输出描述

对于每次询问,输出一行答案。如果可以通过重新排列组成"Baidu",则输出"Yes",否则输出"No"。

示例1

输入输出示例仅供调试,后台判题数据一般不包含示例。

输入

4
Baidu
baidu
Baidu
bbdu

输出

Yes
No
Yes
No

思路:所谓重新排列后可以变成"Baidu"其实就是要求输入的串满足B、a、i、d、u五个字符各有一个,实现方式有很多。

#include<iostream>
#include<string>
using namespace std;
int main(){
	int T, count_B, count_a, count_i, count_d, count_u;
	string str;
	cin >> T;
	while(T--){
		cin >> str;
		count_B = count_a = count_i = count_d = count_u = 1;
		for(char ch:str){
			switch(ch){
				case 'B':-- count_B;
						if(count_B < 0){
							goto label;
						}
						break;
				case 'a':-- count_a;
						if(count_a < 0){
							goto label;
						}
						break;
				case 'i':-- count_i;
						if(count_i < 0){
							goto label;
						}
						break;
				case 'd':-- count_d;
						if(count_d < 0){
							goto label;
						}
						break;
				case 'u':-- count_u;
						if(count_u < 0){
							goto label;
						}
						break;
			}
		}
		label: cout << (count_B + count_a + count_i + count_d + count_u == 0 ? "Yes\n" : "No\n");
	}
	return 0;
}

题目2

给定一个整数x,请你构造—个仅由'r'、'e'、'd'三种字符组成的字符串,其中回文子串的数量恰好为x。
字符串的长度不得超过10^5。

 输入描述

一个正整数x。
1<=x<=10^9

输出描述

输出一个仅由'r'、'e'、'd'三种字符组成的字符串,长度不得超过10^5。有多解时输出任意即可。

示例1

输入输出示例仅供调试,后台判题数据一般不包含示例。

输入

3

输出

red

说明

输出"dd"也可以通过本题

思路:针对说明的讲解--存在3个回文串,d、d、dd。那么这道题要怎么解?最暴力的方式肯定是我们直接按照每个位置三种字符的方式生成串,再去查询串中有多少回文串进行取舍。然而这种方式复杂度非常的高,有没有什么简单的生成方式?

我们需要明确的是,对于一个长度为n的串,当它只由一种字符构成时,它的回文子串数量是最多的。这一点其实挺显而易见的,例如rerrrrrer没有长度为2的回文串,而rrr存在两个长度为2的回文串,不过它们都是rr

现在我们来递推一下,当字符串为r时,其回文子串数量为1;当字符串为rr时,其回文子串数量为两个r的回文子串数量2加上自身1,一共3;我们发现,对于一个长度为i的连续同字符的串例如rrr...rrr,他会有iri-1rr,...,1个rrr...rrr, 也就是说,我们定义\large palindrome[i]表示长度为i的字符串的最大回文子串数量,则有:

palindrome[i]=\sum_{j=1}^{i}j

同时,我们只要通过r....re....ed....dr.....re....ed...d...的方式生成串,就可以保证回文串只可能产生在每一个r...re...ed...d区间内。

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;

const int maxn = 1e5 + 7;
int palindromeNum[maxn];

int main(){
	int x, palindromeLen, *p, generateLen;
	char chList[3] = {'r', 'e', 'd'};
	const int charMod = 3;
	int charIdx = 0;
	string palindromeStr = "";
	cin >> x;
	palindromeNum[1] = 1;
	for(palindromeLen = 2; palindromeNum[palindromeLen - 1] <= x; ++ palindromeLen){
		palindromeNum[palindromeLen] = palindromeNum[palindromeLen - 1] + palindromeLen;
	}
	-- palindromeLen;
	x -= palindromeNum[palindromeLen - 1];
	palindromeStr = palindromeStr + string(palindromeNum[palindromeLen - 1], 'r');
	while(x > 0){
		p = lower_bound(palindromeNum + 1, palindromeNum + palindromeLen, x);
		if(*p > x){
			-- p;
		}
		generateLen = *p;
		x -= generateLen;
		charIdx = (charIdx + 1) % charMod; 
		palindromeStr = palindromeStr + string(generateLen, chList[charIdx]);
	}
	cout << palindromeStr;
	return 0;
}

题目3

小红拿到了一棵树,每个节点被染成了红色或者蓝色。小红定义每条边的权值为:
删除这条边时,形成的两个子树的同色连通块数量之差的绝对值。
小红想知道,所有边的权值之和是多少?

输入描述

第一行输入一个整数n,代表节点的数量。
第二行输入一个长度为n且仅由'R'和'B'两种字符组成的字符串。
第i个字符为'R'代表i号节点被染成红色,为'B'则被染成蓝色。
接下来的n-1行,每行输入两个正整数u和v,代表节点u和节点v相连。

输出描述

一个整数,代表所有边的权值之和。

示例

5
R B R R B
1 2
1 3
2 4
3 5
8

输入

5
R B R R B
1 2
1 3
2 4
3 5
8

输出

5
R B R R B
1 2
1 3
2 4
3 5
8

思路:首先我们需要建树,把无根树转成有根树。然后我们直接在书上进行搜索,每个节点维护两个值(RedNum与BlueNum),同时保留全局的GlobalRedNum与GlobalBlueNum,这样另一棵子树的红蓝节点数为GlobalRedNum-RedNum和GlobalBlueNum-BlueNum,直接遍历这棵树就行。

ss

题目4

小红拿到了一棵树,每个节点被染成了红色或者蓝色。小红定义每条边的权值为:删除这条边时,形成的两个子树的同色连通块数量之差的绝对值。

小红想知道,所有边的权值之和是多少?

输入描述

第一行输入一个整数n,代表节点的数量。
第二行输入一个长度为n且仅由'R'和'B'两种字符组成的字符串。

输出描述

思路:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值