一套超级简单而又神奇的题目
(Upd:文章部分转载,已署名)

Grades

Liuzhe dalao出的签到题

而且卡了冒泡排序这种朴素算法……

尽管如此,方法还是有很多。比如手打快排,手打归并……

但在这里,我们使用STL内置的$sort$函数。

另外需要注意的是,由于我们需要使用结构体进行交换,因此,我们需要手打$cmp$函数

基本没什么难度吧……

Code

#include<iostream>
#include<algorithm>

#define N 20005

using namespace std;

struct Student{
int num;
int grade;
}stu[N];

bool cmp(Student a , Student b){
return a.grade > b.grade;
}

int n;

int main(){
cin >> n;
for(int i = 1; i <= n; i ++){
cin >> stu[i].num >> stu[i].grade;
}
sort(stu + 1 , stu + 1 + n , cmp);
for(int i = 1; i <= n; i ++){
cout << stu[i].num <<" "<< stu[i].grade << endl;
}
return 0;
}
//Witten By Payphone-X

Unturned

Struct瓶子 julao出的数据结构题……

考的是一种极其基础的数据结构:

我们重新读一遍题目,会发现上边有三种操作:

  • $1$,$s$,$a$,$b$ 表示从你现在的所在地前往到另一个名称为$s$,物资值为$a$,危险值为$b$的地方。

  • $2$ 表示从你现在的所在地返回到你上一次前往的地方(原路返回)。若现在在$Liberator$号上,则无视。

  • $3$ 表示查询你现在的所在地的名称、物资值和危险值。若现在在$Liberator$号上,则输出$-1$。

其中,三种操作分别对应了栈的操作中的入栈弹出栈顶获取栈顶元素

所以我们可以写一个栈,直接进行模拟即可。

还有什么的话,就是

注 意 细 节

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<stack>
#define N 20001

using namespace std;

struct Place{
string name;
int thing;
int danger;
}p[N];

stack<Place> S;

pair<int , string> Thing_max;
pair<int , string> Danger_max;

int n;
int p_num = 1;
int opt;

int main(){
cin >> n;
p[p_num].name = "Liberator";
p[p_num].thing = 0;
p[p_num].danger = 0;
S.push(p[p_num]);
for(int i = 1; i <= n; i ++){
cin >> opt;
if(opt == 1){
p_num ++;
cin >> p[p_num].name >> p[p_num].thing >> p[p_num].danger;
if(p[p_num].thing > Thing_max.first){
Thing_max.first = p[p_num].thing;
Thing_max.second = p[p_num].name;
}
if(p[p_num].danger > Danger_max.first){
Danger_max.first = p[p_num].danger;
Danger_max.second = p[p_num].name;
}
S.push(p[p_num]);
}
if(opt == 2){
if(S.top().name == "Liberator"){
continue;
}
S.pop();
}
if(opt == 3){
if(S.top().name == "Liberator"){
cout << "-1" << endl;
continue;
}
cout << S.top().name <<" "<< S.top().thing <<" "<< S.top().danger << endl;
}
}
cout << S.top().name << endl;
cout << Thing_max.second << endl;
cout << Danger_max.second << endl;
return 0;
}
//Written By Payphone-X

The Best String

这题是作者菜鸡出的一道字符串问题……

如果 这道题的题意如果使用一句话总结出来的话就是:

将一个01字符串拆分成多个01子串,要求其中每一个子串中0与1的数量不同。

既然如此,我们就从子串的长度入手进行分析。

一个字符串的长度必定是奇数偶数(废话)

若是奇数的话,0与1的数量本来就不可能相等,所以我们也就不需要拆分,直接输出即可。

若是偶数的话,我们可以考虑偶数可以由两个奇数组成,比如$26 = 11 + 15$

所以说我们的任务就是要找到这两个奇数。

题目里又有另一句话

  • 但Herself32是个左撇子,so……她希望拆分后左边的字符串的长度尽量的短

不难看出,左边的字符串最短时长度为$1$,即我们只需要把该字符串的第一位单独拆分出来即可。

最后别忘了特判长度为偶数且输入的字符串就不需拆分的状况

Code

#include<iostream>
#include<cstdio>
#define N 101

using namespace std;

int n;
string a;
int num0 , num1;

int main(){
cin >> n;
cin >> a;
if(n % 2 != 0){
cout << 1 << endl;
cout << a << endl;
return 0;
}
for(int i = 0; i < n; i ++){
if(a[i] == '0'){
num0 ++;
}
else{
num1 ++;
}
}
if(num0 != num1){
cout << 1 << endl;
cout << a << endl;
return 0;
}
else{
cout << 2 << endl;
cout << a[0] << " ";
for(int i = 1; i < n; i ++){
cout << a[i];
}
}
return 0;
}
//Written By Payphone-X

TarjanLusa

(本部分转载于Herself32’s Blog,之前转载时忘记署名,实在抱歉。望原作者原谅。)

毒瘤Herself32,出题粘PDF

咳咳,这是一道大模拟题目。

首先,我们开一个数组直接模拟球位,然后直接把题目中的左右调换,这样更便于操作。

然后观察题意,我们发现,如果激发一个球之后,它将从数组第一个位置消失(弹出),而如果生成球,就要从后面加入数组。

这不就是一个队列嘛!

但是我们这里并不需要循环队列,直接用$head$指针操作即可。

顺便提醒大家几个小细节:

  1. 当球位不够时不能直接添加,而是要激发队首的几个球。
  2. 被动和技能不一样,触发被动并不会使球消失。
  3. 在生成球的时候,如果球位不够,则激发队首球1次

好了,那么$80+$行代码也就写出来了。

(由于作者比较菜,所以作者并没有重写这道题,直接使用的$std$。这说明我实在是菜爆了啊)

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

#define N 500010
#define mo 1000000007

using namespace std;


int n, s;
int damage, block;
int energe[N];
char q[N], str[10];
int front = 1, tail = 1, size = 3;

void activate(int p, int x){
if (q[p] == 'e')
damage = (damage + 1ll * max(8 + s, 0) * x) % mo;
else if (q[p] == 'i')
block = (block + 1ll * max(5 + s, 0) * x) % mo;
else if (q[p] == 'd')
damage = (damage + 1ll * energe[p] * x) % mo;
else
front--;
front++;
}

void use(int p, int x){
if (q[p] == 'e')
damage = (damage + 1ll * max(3 + s, 0) * x) % mo;
else if (q[p] == 'i')
block = (block + 1ll * max(2 + s, 0) * x) % mo;
else if (q[p] == 'd')
energe[p] = (energe[p] + 1ll * max(s + 6, 0) * x) % mo;
else
;
}

int main(){
scanf("%d", &n);
q[1] = 'e';
for (int a = 1; a <= n; a++)
{
int opt;
scanf("%d", &opt);
if (opt == 1)
{
scanf("%s", str + 1);
int l = strlen(str + 1);
for (int b = 1; b <= l; b++)
{
q[++tail] = str[b];
if (str[b] == 'd')
energe[tail] = 6;
}
while (tail - front + 1 > size)
activate(front, 1);
}
if (opt == 2)
{
int x;
scanf("%d", &x);
activate(front, x);
}
if (opt == 3)
{
int i, x;
scanf("%d%d", &i, &x);
use(front + i - 1, x);
}
if (opt == 4)
{
int x;
scanf("%d", &x);
s += x;
}
if (opt == 5)
{
int x;
scanf("%d", &x);
size += x;
}
}
printf("%d %d\n", damage, block);
return 0;
}

后记

今天的比赛题目并没有特别难,但每一个题都需要无限的细心,特别是$T2$与$T4$

$T3$表面上是一道字符串题,但主要考察的是同学们的数学思想与分析能力。需要冷静分析。

$T1$是对最最基础的算法进行考察,属于签到题。这种题在考场上绝对不能出错!!!

综上,这次考试的高分秘诀就在于:细心冷静坚持

最后祝大家在今后的考试中能够取得更好的成绩

THE END