目录
- [A - A Unique Letter](https://atcoder.jp/contests/abc260/tasks/abc260_a)
- [B - Better Students Are Needed!](https://atcoder.jp/contests/abc260/tasks/abc260_b)
- [C - Changing Jewels](https://atcoder.jp/contests/abc260/tasks/abc260_c)
- [D - Draw Your Cards](https://atcoder.jp/contests/abc260/tasks/abc260_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函数,为三次排序的依据
即:
- 按照数学降序排序
- 按照英语降序排序
- 按照总分降序排序
依次进行三个排序(每次排序前将已录取的学生排除)
将已录取的学生按照学号升序排序并输出。
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提供的提醒
尾声
谢谢阅读