[阿里笔试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);
}