阿里春招笔试2020.4.1(贪心/优队)

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

题目一(贪心)

给一串二进制字符串如00011001,希望把他改为全为0,如果更改某个字符,那么他两边的字符也要更改,例如把第二位的0换成1,那么就变成了11111001. 求最少翻转次数。如果无法全0,输出NO。
思路:贪心。分两种情况,第一个值修改/不修改,之后每个值都会受前面数影响,如果到了最后一个位置为1,说明当前处理无解。两者取最小值即可。

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

char s[maxn],s2[maxn];
int n;
void f(char &c) {
	c = '0'+('1'-c);
}
int cal(char s[]) {
	int res = 0;
	for(int i = 0;i < n-1;++i) {
		if(s[i] == '1') {
			f(s[i]);
			if(i+1 < n) f(s[i+1]);
			if(i+2 < n) f(s[i+2]);
			res++;
		}
	}
	if(s[n-1] == '1') return -1;
	return res;
} 
int main() {
	scanf("%s",s);
	n = strlen(s);
	if(n == 1) {
		int res = s[0]-'0';
		printf("%d\n",res);
		return 0;
	}
	strcpy(s2,s);
	int res = cal(s2);
	if(n > 2) {
		f(s[0]);
		f(s[1]);
//		printf("After :%s\n",s);
		int res2 = cal(s);
		if(res2 != -1) {
			++res2;
			if(res == -1 || res > res2)
				res = res2;
		}
	}
	if(res == -1) puts("NO");
	else printf("%d\n",res);
} 

题目二(优队)

有N个怪兽,M个弓箭,每个怪兽有生命值,每个弓箭有杀伤力和价值,每个怪兽只能用一支弓箭攻击,弓箭杀伤>=怪兽生命时可消灭怪兽,求使用弓箭的最小价值。如无法消灭,返回-1。
思路:优队,维护最小堆。

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

int n,m;
int monster[maxn];
struct node {
	int hit;
	int val;
	bool operator <(const node &a) {
		return hit < a.hit;
	}
}arrow[maxm];


int main() {
	scanf("%d%d",&n,&m);
	for(int i = 0;i < n;++i) 
		scanf("%d",&monster[i]);
	for(int i = 0;i < m;++i) 
		scanf("%d%d",&arrow[i].hit,&arrow[i].val);
	sort(monster,monster+n);
	sort(arrow,arrow+m);
	ll ans = 0;
	priority_queue<int,vector<int>,greater<int> > q;
	for(int i = n-1,j = m-1;i >= 0;--i) {
		while(j && arrow[j].hit >= monster[i]) {
			q.push(arrow[j].val);
			j--;
		}
		if(q.empty()) {
			ans = -1;break;
		}
		ans += q.top();
		q.pop();
	}
	printf("%lld\n",ans);
}
发布了152 篇原创文章 · 获赞 2 · 访问量 6445

猜你喜欢

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