阿里春招笔试2020.3.27(贪心/差分/概率)

申明:大概题意是从牛客网讨论区嫖的,题目的输入、输出以及数据数据范围也有些不知,大家看看思路就好,这些细节就不管了QAQ。有错欢迎纠正~
3.27

题目一(贪心)

给定字符串s1,s2,求从s1变为s2的最小移动次数(要求每一次只能从s1选取任意一个字符放到s1最后)
思路:贪心。首先如果两个字符串对应的字符数不匹配的话,那么答案一定是-1。否则的话,我们一定可以构造新的s,使得和t相等。由于s的字符可以移动,而t的字符不能移动。所以该本质是求s的最长不连续子串,使得和t的前缀子串匹配。由于是匹配t的前缀子串,那么我们可以贪心的匹配即可,每遇到一个s的字符和t的当前字符匹配,则t的字符向前移动一位。最终答案就是n-可以匹配 的最多位数。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;

char s[maxn],t[maxn];
int mp1[27],mp2[27];//统计各个字符数 
int n;
int main() {
	scanf("%d",&n);
	scanf("%s%s",s,t);
	int j = 0;
	for(int i = 0;i < n;i++) {
		if(s[i] == t[j]) j++;
		mp1[s[i]-'a']++;
		mp2[t[i]-'a']++;
	}
	bool flag = 1;
	for(int i = 0;i < 26;i++) {
		if(mp1[i] != mp2[i]) {
			flag = 0;break;
		}
	}
	if(flag == 0) printf("-1\n");
	else printf("%d\n",n-j);
	return 0;
} 

题目二(差分/概率)

参考
给定N个区间(范围1~2000),每个区间包含左右范围(1<=L<=R<=2000),每次从所有区间范围内选择一个整数,求所有选出的数的最小值的期望。
思路:这里单个值的概率不好求,但是反过来我们可以先求 > = p o s >=pos 的概率,继而用差分即可求出单个值的概率。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2010;

int n;
int l[maxn],r[maxn];
double p[maxn];
int main() {
	int mn = 2000,mx;//确定最小值范围 
	scanf("%d",&n);
	for(int i = 0;i < n;i++) 
		scanf("%d",&l[i]),mn = min(mn,l[i]);
	for(int i = 0;i < n;i++) 
		scanf("%d",&r[i]);
	double ans = 0;
	bool flag = 1;
	for(int pos = mn;pos <= 2000;++pos) {
		double tmp = 1.0;
		for(int i = 0;i < n;++i) {
			if(r[i] < pos) {
				flag = 0;break;
			}
			if(l[i]<=pos && pos <= r[i])
				tmp *= 1.0*(r[i]-pos+1)/(r[i]-l[i]+1);
		}
		if(!flag) {
			mx = pos-1;break;
		}
		p[pos] = tmp;//计算出最小值>=pos的概率 
	}
	for(int i = mn;i < mx;++i) {
		p[i] -= p[i+1];//差分计算最小值为i的概率 
		ans += p[i]*i; 
	}
	ans += p[mx]*mx;
	printf("%.6f\n",ans);
} 
/*
2
1 2
3 3 
*/
发布了152 篇原创文章 · 获赞 2 · 访问量 6442

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/105278826
今日推荐