一套超级简单而又神奇的题目
(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; }
|
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; }
|
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; }
|
TarjanLusa
(本部分转载于Herself32’s Blog,之前转载时忘记署名,实在抱歉。望原作者原谅。)
毒瘤Herself32,出题粘PDF
咳咳,这是一道大模拟题目。
首先,我们开一个数组直接模拟球位,然后直接把题目中的左右调换,这样更便于操作。
然后观察题意,我们发现,如果激发一个球之后,它将从数组第一个位置消失(弹出),而如果生成球,就要从后面加入数组。
这不就是一个队列嘛!
但是我们这里并不需要循环队列,直接用$head$指针操作即可。
顺便提醒大家几个小细节:
- 当球位不够时不能直接添加,而是要激发队首的几个球。
- 被动和技能不一样,触发被动并不会使球消失。
- 在生成球的时候,如果球位不够,则激发队首球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