ABC 260 A~D 题解

A - A Unique Letter

代码

#include <iostream>
#include <cstring>
using namespace std;

string s;

int main()
{
	cin  >> s;
	if(s[0] != s[1] && s[0] != s[2])
	{
		cout << s[0];
		return 0;
	}
	if(s[1] != s[2] && s[0] != s[2])
	{
		cout << s[2];
		return 0;
	}
	if(s[0] != s[1] && s[1] != s[2])
	{
		cout << s[1];
		return 0;
	}
	cout << -1;
	return 0;
}

题意疏通

给你一个长度为3的字符串,输出其中任意一个不和其他字母重复的字母
如果没有,输出-1

输入格式

S

输出格式

ans

思路点拨

手动判断一下每个字母是否有重复
输出即可

B - Better Students Are Needed!

代码

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

struct Stu
{
	int m, e, num;
};

Stu ls[2010];
int n, x, y, z, id = 1;
vector<int> v;

bool cmp1(Stu x, Stu y)
{
	if(x.m == y.m) return x.num < y.num;
	return x.m > y.m;
}

bool cmp2(Stu x, Stu y)
{
	if(x.e == y.e) return x.num < y.num;
	return x.e > y.e;
}

bool cmp3(Stu x, Stu y)
{
	if(x.m + x.e == y.m + y.e) return x.num < y.num;
	return x.m + x.e > y.m + y.e;
}

int main()
{
	cin >> n >> x >> y >> z;
	for(int i = 1; i <= n; i++)
	{
		int t;
		cin >> t;
		ls[i].m = t;
		ls[i].num = i;
	}
	for(int i = 1; i <= n; i++) cin >> ls[i].e;
	
	sort(ls + 1, ls + n + 1, cmp1);
	for(id = 1; id <= x; id++) v.push_back(ls[id].num);
	
	sort(ls + id, ls + n + 1, cmp2);
	for(int i = 1; i <= y; i++, id++) v.push_back(ls[id].num);
	
	sort(ls + id, ls + n + 1, cmp3);
	for(int i = 1; i <= z; i++, id++) v.push_back(ls[id].num);
	
	sort(v.begin(), v.end());
	for(int i = 0; i < v.size(); i++) cout << v[i] << endl;
	return 0;
}

题意疏通

N N N个学生,第 i i i个学生编号为 i i i, 数学、英语成绩分别为 A   i   A~i~ A i  B   i   B~i~ B i ,学校将依次录取数学前 X X X名,英语前 Y Y Y名,总分前 Z Z Z名(已经录取过的不在接下来的排名中考虑)
按照学号的从小到大输出被录取的学生

输入格式

N X Y Z
A1 A2 A3 … AN
B1 B2 B3 … BN

输出格式

ans1
ans2

ansX+Y+Z

思路点拨

用结构体存储学生的数学、英语成绩以及学号,定义三个 c m p cmp cmp函数,为三次排序的依据
即:

  1. 按照数学降序排序
  2. 按照英语降序排序
  3. 按照总分降序排序

依次进行三个排序(每次排序前将已录取的学生排除)

将已录取的学生按照学号升序排序并输出。

C - Changing Jewels

代码

#include <iostream>
using namespace std;

typedef long long LL;

LL n, x, y;

int main()
{
	cin >> n >> x >> y;
	LL r = 1, b = 0;
	for(int i=n; i>1; i--)
	{
		b += r * x;
		r += b;
		b *= y;
	}
	cout << b;
	return 0;
}

题意疏通

高桥有1个 N N N级的红宝石
它可以执行以下操作:

  • 将红宝石降低一级,并获得 X X X个和降低前红宝石等级相等的蓝宝石
  • 将蓝宝石变为低一级的红宝石,并获得 Y Y Y个降低一级的蓝宝石

请输出最终高桥最多获得多少1级蓝宝石

输入格式

N X Y

输出格式

ans

思路分析

红宝石N → 红N-1 + 蓝N * X X X
蓝宝石N → 红N-1 + 蓝N-1 * Y Y Y

等量代换得:
红宝石N → 红N-1 + (蓝n-1 * Y Y Y + 红N-1)* X X X
即:
红宝石N → 红N-1 * ( X X X + 1) + 蓝 * X X X * Y Y Y

再看一遍代码
懂了吧

D - Draw Your Cards

代码

#include <iostream>
#include <cstring>
#include <set>
using namespace std;

const int N = 200010;

int n, k, x, p[N], ans[N], under[N], top[N], idx;

int upper(int t)
{
	int l = 1, r = idx;
	while(l < r) 
	{
		int mid = l + r >> 1;
		if(top[mid] > t) r = mid;
		else l = mid + 1;
	}
	return l;
}
int main()
{
	memset(ans, -1, sizeof(ans));
	cin >> n >> k;
	for(int i = 1; i <= n; i++)
	{
		cin >> x;
		int t;
		if(x > top[idx]) 
		{
			top[++idx] = x;
			p[x] = 1;
			t = idx;
		}
		else 
		{
			t = upper(x);
			p[x] = p[top[t]] + 1;
			under[x] = top[t];
			top[t] = x;
		}
		if(p[x] == k)
		{
			while(x)
			{
				ans[x] = i;
				x = under[x];
			}
			for(int j = t; j < idx; j++)
			{
				top[j] = top[j + 1];
			}
			idx--;
		}
//		else
//		{
//			while(t > 1 && top[t] < top[t-1])
//			{
//				top[t] = top[t-1];
//				t--;
//			}
//			top[t] = x;
//		}
	}
	for(int i = 1; i <= n; i++) 
	{
		cout << ans[i] << endl;
	}
	return 0;
} 

题意疏通

N N N个数字,依次输入
对于每一个数字,找到已经生成的栈中栈顶大于该数字的最小值,并将该数字 p u s h push push到栈中
若没有这样的栈,则新建一个只有该数字的栈

每当一个栈内的数据总量达到 K K K,则“吃掉”这个栈,被“吃掉”的栈不能再push新元素

输出每一个元素被“吃掉”的时间(对于没有被吃掉的元素,输出-1

输入格式

N K
A1 A2 … AN

输出格式

ans1
ans2

ansN

思路点拨

模拟一下即可

用一个反向并查集(即存储每一个节点的子节点)存储栈
top数组存储每一个栈的栈顶,并维护top的单调性(其实不用人为维护,正常执行操作,数组的单调性一直存在)

对于每一个数字,判断其是否大于最后一个栈的栈顶

  • 如果是,新建一个栈
  • 否则,用二分查找每一个栈顶(top有单调性),并将其 p u s h push push到该栈中(此处使用并查集操作,将本数对应的under设为原本的top并更新top

判断该栈是否被“吃掉”

  • 如果是:将此栈栈顶从top中删除
  • 否则,直接进入下一个循环

关于单调性的说明

本代码段中有一个被注释掉的 w h i l e while while循环,相信了解 插入排序 插入排序 插入排序的同学们都明白其作用:维护top的单调性
但是,我把它注释掉了

有人可能不理解了:你既然不维护其单调性,二分怎么进行呢?

不需要维护。

top数组自带单调性

原因如下:

  • top数组为空时,其自带单调性
  • 若输入数据过大,需要新建栈,该栈将被放在top数组最后,则top数组依然保持单调递增
  • 若输入数据被 p u s h push push到某栈的栈顶,它一定大于它前面的一个栈顶,否则它将被 p u s h push push到前一个栈顶;它一定小于本站栈顶,因为否则它不会被 p u s h push push到本栈,所以,它也小于后一个栈顶(top数组在执行本操作之前拥有单调性),所以,该数组依然保持单调递增

综上所述:top数组在任何情况下都拥有单调性,不需要额外维护

感谢@Triples提供的提醒

尾声

谢谢阅读

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值