这次考试整体来说比较简单,几乎都是暴力,模拟,没有涉及到高级一点的算法和数据结构。
我考试时得了4265分,其实每道题想一想都会做,考试时没有AC的原因在于
1.时间不够,没有充分的时间思考。
2.看到比较长的题目就有畏难情绪,没有认真分析。
3.不够细心,忘了开long long,导致在这种赛制下丢了时间分
题目背景
魔方,奇妙的玩具!一次次普通的转动,竟能将杂乱无章的色块转回到初始的、完美的状态! zyl
十分喜欢魔方,并且,在班上,复原正阶魔方就属他最快。 一天,他传纸条问她:“你会复原魔方吗?” “不会。” 没过几天,在 zyl
坐在座位上玩魔方的时候,她走了过来:“你说过要教我魔方的哦!” zyl 愣了一下,因为他印象里好像没说要教她。不过,他还是爽快地答应了。
于是,zyl 开始给她上魔方的第一课——认识魔方… 然而,还没等教会她复原魔方,zyl 就离开学校了…… zyl
能够复原一个又一个魔方,却无法复原那美好的青春……题目描述
正阶魔方的形状是正方体,每个面由相等的若干个小正方形构成。对于 n n n( n ≥ 2 n \geq 2 n≥2)阶魔方,它的六个面中的每个面均由
n × n n\times n n×n 个小正方形构成。魔方的六个面被染上了两两不同的颜色,被染上色的小正方形又构成一个个小正方体,这些小正方体被称为「块」。
容易发现,每个块被染色的面的数量 x x x 均满足 1 ≤ x ≤ 3 1\leq x\leq 3 1≤x≤3。根据这个性质,魔方有三个围绕块的重要概念:
- 角块:有三个面被染色的块。一个 n n n 阶魔方的角块数总是 8 8 8。
- 棱块:只有两个面被染色的块。一个 n n n 阶魔方的棱块数为 12 × ( n − 2 ) 12 \times (n - 2) 12×(n−2)。
- 中心块:只有一个面被染色的块。一个 n n n 阶魔方的中心块个数等于 6 × ( n − 2 ) 2 6\times (n-2)^2 6×(n−2)2。
现在给你一个正阶魔方的阶数 n n n,请你依次求出它的角块,棱块,中心块的数量。
输入格式
输入共一行一个整数 n n n,表示魔方的阶数。
输出格式
输出共一行三个整数,依次表示 n n n 阶魔方的角块,棱块,中心块的数量。
样例 #1
样例输入 #1
3
样例输出 #1
8 12 6
提示
数据规模与约定
- 对于 40 % 40\% 40% 的数据, 2 ≤ n ≤ 17 2\leq n\leq 17 2≤n≤17。
- 对于 100 % 100\% 100% 的数据, 2 ≤ n ≤ 1 0 6 2\leq n \leq 10^{6} 2≤n≤106。
前面的题目背景和题目描述根本不用看,那些什么块什么涂色的直接跳过(我直到现在都还没看 ),这种题直接瞄准给出的公式即可(这道题真善良,公式都给了 )。
#include
using namespace std;
long long n;
int main(){
cin >> n;
cout << 8 << " " << 12 * (n - 2) << " " << 6 * (n - 2) * (n - 2);
}
记得开long long.
光阴似箭,日月如梭。去岁初秋,微风缕缕,朝阳独挂,霞光普照。
一个平凡的开学季,zyl 来到了新的学校。
当时一切充满希望,前途一片光明。
zyl 来到新的学校。
学校很大,他很难找到自己要去哪一座教学楼。
zyl 的班主任告诉了他教室在几楼,但进入学校大门后映入眼帘的是三座教学楼:图书馆,综合楼,艺术楼。这三栋教学楼的最高楼层数分别为 3 , 5 , 9 3, 5, 9 3,5,9。
现在 zyl 得知,他想要找的教室在这座三栋教学楼中的一栋中。同时,zyl 掌握了如下信息:
显然,教室所在的楼层数一定不大于其所在的教学楼的最高楼层数。在满足该条件的基础上,他又得知,教室处在所有可能的教学楼中人流量最小的一栋。
现在,请你按照上述条件,帮助他找出,他的教室处在哪栋教学楼上。
输入共两行。
第一行一个整数 n n n,表示教室所在的楼层数。
第二行三个整数 a , b , c a, b, c a,b,c,分别代表图书馆,综合楼,艺术楼的人流量。
输出共一行一个字符串,表示教室所在的教学楼。
其中,library
表示图书馆,comprehensive
表示综合楼,art
代表艺术楼。
4
20 50 100
comprehensive
2
30 80 20
art
教室在 4 4 4 楼,图书馆的最高楼层为 3 3 3,因此教室不可能在图书馆。而剩下两栋楼中,综合楼的人流量最小,所以教室在综合楼。
分类讨论,n>5,n>3,n<=3,注意最后一种情况是小于等于
#include
using namespace std;
int n,a,b,c;
int main(){
cin >> n >> a >> b >> c;
if(n > 5){
cout << "art";
return 0;
}
if(n > 3){
if(b < c) cout << "comprehensive";
else cout << "art";
return 0;
}
if(n <= 3){
if(a < b && a < c) cout << "library";
else if(b < a && b < c) cout << "comprehensive";
else cout << "art";
return 0;
}
}
题目背景
各式各样的课桌,封存了青春最宝贵的东西。书本、文具都是其次,桌子里往往还会有零食,玩具,饮料……
当然,课桌能装的东西特别多,每个人的课桌都是不一样的。课桌里装的东西可能比书包里的东西还丰富。 zyl
的课桌里面十分乱,不过他总能轻松找到一本格子本……有时候,甚至还会有一个象棋的棋盘,这是为什么呢? 一切美好都起源于一次座位的调换……
让我们帮 zyl 回忆起那一幕……题目描述
自习课上,同学们可以适当地互相换座位。zyl 想要换到她的后面一排……
可是,想要换到那里,需要依次和 n n n
个同学换座位。大家都很爱学习,课桌上都摆着若干本书。与一个同学换座位,虽然不需要把整个课桌都调换位置,但需要把双方课桌上的书调换位置。zyl 自己有 x x x 本书。他每和一个人换座位,都会把双方课桌上的书调换位置,消耗双方书数量之和的体力。
请你求出,他最后消耗的体力的数量。
输入格式
输入共两行。
第一行两个整数 n , x n, x n,x,分别表示 zyl 换座位的路上需要经过的课桌数量和 zyl 自己课桌上的书的数量。 第二行 n n n 个整数
a 1 , a 2 , ⋯ , a n a _ 1, a _ 2, \cdots, a _ n a1,a2,⋯,an,表示 zyl 换座位路上遇到的课桌上书本的数量。输出格式
共一行一个整数,表示 zyl 消耗的体力值。
样例 #1
样例输入 #1
4 3 1 3 2 4
样例输出 #1
22
提示
样例 1 解释 和第一个同学换座位,花费 3 + 1 = 4 3+1=4 3+1=4 体力值, 和第二个同学换座位,花费 3 + 3 = 6 3+3=6 3+3=6 体力值, 和第三个同学换座位,花费 3 + 2 = 5 3+2=5 3+2=5 体力值, 和第四个同学换座位,花费 3 + 4 = 7 3+4=7 3+4=7 体力值。
总共花费 4 + 6 + 5 + 7 = 22 4+6+5+7=22 4+6+5+7=22 体力值。
数据范围与约定 设同学桌上书本的总数为 s s s,即 s = a 1 + a 2 + a 3 + … a n s = a_1 + a_2 + a_3 + \dots a_n s=a1+a2+a3+…an。
- 对于 60 % 60\% 60% 的数据, n ≤ 1000 n\leq 1000 n≤1000, x ≤ 100 x \leq 100 x≤100, a i , s ≤ 1 0 7 a_i,s \leq 10^7 ai,s≤107。
- 对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 2 × 1 0 6 1\leq n\leq 2\times10^{6} 1≤n≤2×106, 1 ≤ x ≤ 1 0 4 1\leq x \leq 10^{4} 1≤x≤104, 1 ≤ a i , s ≤ 2 × 1 0 9 1\leq a_i,s\leq 2\times10^{9} 1≤ai,s≤2×109。
那一天是周日,zyl 成功地换到了她的后面,放学的时候,他们下了一把五子棋……
直接n*x加a数组的和,不用多说。
#include
using namespace std;
long long n,x,s,a;
int main(){
cin >> n >> x;
s=n*x;
while(n--){
cin >> a;
s+=a;
}
cout << s ;
}
题目背景
教室很小,小到只能装下几十个人。 教室很大,大到容下我们的整个青春。 一场故事就要开始了…
题目描述
zyl 来到了新教室,数学老师想让他帮忙安排一下座位。
老师要求桌子的总数和学生的总数一样多,但是 zyl 不知道班级中一共有多少名学生。不过,在教室的后面有 n n n 个柜子,编号为 1 ∼ n 1\sim n 1∼n,第 i i i 个柜子由 a i × b i a_i\times b_i ai×bi 个格子组成,且每个格子都被 c i c_i ci
个学生共同使用。一个学生会且只会使用一个柜子中的一个格子。通过这些信息,zyl 就能够算出学生的总数了。现在要把桌子排成 m m m
列,要求尽量把桌子摆成一个整齐的矩形,即,尽量保证每一列的桌子一样多。但如果最后多出几张桌子无法组成完整的一排,就将这些桌子在原最后一排的后面摆成新的一排。zyl 想要知道,所有的桌子摆好后,一共有多少排,最后一排又有多少张桌子。
输入格式
输入共 n + 1 n+1 n+1 行。
第一行两个整数 n , m n,m n,m,分别表示柜子的个数和桌子的列数。 接下来 n n n 行,每行三个整数 a i , b i , c i a_i,b_i,c_i ai,bi,ci,描述第
i i i 个柜子的信息。输出格式
输出共一行两个整数,分别表示摆完桌子后的总排数和最后一排的桌子数量,用空格隔开。
样例 #1
样例输入 #1
3 8 2 3 3 4 1 3 2 5 2
样例输出 #1
7 2
提示
样例 1 解释 第 1 1 1 个柜子有 2 2 2 行 3 3 3 列,每个格子被 3 3 3 个同学使用,故这个柜子一共有 6 6 6 个格子,有 18 18 18 名同学使用这个柜子。同理可得后两个柜子分别有 12 12 12 名、 20 20 20 名同学使用,故一共有 50 50 50 名同学,代表班级中有
50 50 50 张桌子。桌子需要摆成 8 8 8 列,首先每一列摆 6 6 6 个桌子,此时桌子有 6 6 6 排。其次,剩下 2 2 2 张桌子放在第 6 6 6
排的后面,组成第 7 7 7 排,这样一共有 7 7 7 排桌子,第 7 7 7 排有 2 2 2 张桌子。数据规模与约定
对于 40 % 40\% 40% 的数据,保证桌子按要求能恰好构成一个矩形。 对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1\leq n\leq 100 1≤n≤100, 1 ≤ a i , b i , c i ≤ 10 1\leq a_i,b_i,c_i\leq 10 1≤ai,bi,ci≤10, 1 ≤ m ≤ 50 1\leq m\leq 50 1≤m≤50。
矩阵相加每一行的积,若能整除,输出a/b,b,若不能,输出a/b,a%b.
so easy;
#include
using namespace std;
int n,x,s,p,a;
int main(){
cin >> n >> x;
for(int i= 1; i <= n; i++){
p=1;
for(int j = 1; j <= 3; j++) cin >> a,p*=a;
s+=p;
}
if(s % x == 0) cout << s / x << " " << x;
else cout << s/x +1<< " " << s%x;
}
题目背景
如果朋友不能经常见面,那就多写信,少打电话,以体现真诚。
——《围城》在离别之前,zyl 和她都为对方准备了一封信,多么的默契啊……或许是最后的默契……
双方都准备了信封,除了信以外,还有一些礼物。还记得独行吗?诗中为何以舟为交通工具?因为啊,她在
zyl 走之前送给 zyl 一艘她精心折的小纸船,上面写着:像一艘飘散着香气的独木舟,离开一座小小的荒岛。
题目描述
信是具有重量的。信封有重量,信纸也有重量。由于信封和信纸都很薄,我们认为每平方厘米信封的重量为 x x x 毫克,每平方厘米信纸的重量为 y y y
毫克。 此外,有的信封中还会有一些礼物,这些礼物一定有重量。zyl 收到了 n n n 封信,他能精确测量出每封信中信封的表面积 S S S(单位:平方厘米)、信纸的面积
s s s(单位:平方厘米)以及整封信的重量
M M M(单位:毫克),保证这三个数据都是整数。在拆开信件的过程中,他会按照如下规则积累惊喜值(初始时惊喜值为 0 0 0):
- 如果信封没有任何礼物(即信封中礼物重量为 0 0 0),他的惊喜值不变。但是,如果连续 b b b 封及以上的信里都没有礼物,则从第 b b b 封信开始,每拆开一封没有礼物的信,zyl 的惊喜值都会减半,然后向下取整,直到拆开一封有礼物的信。如果惊喜值原本即为
0 0 0,则不会变化。- 如果信封里有礼物,设礼物的质量为 M ′ M' M′ 毫克,则 zyl 的惊喜值会增加 M ′ M' M′。如果礼物的质量大于信封和信纸的总质量,则会额外增加 0.5 M ′ 0.5\ M' 0.5 M′,然后向上取整。如果连续 a a a
封及以上的信里有礼物,则从第 a a a 封信开始,每拆开一封有礼物的信,zyl 的惊喜值都会在计算完这次本身的加成后再乘
2 2 2,直至拆开一封没有礼物的信。现在按照 zyl 拆信的顺序给出 n n n 封信的信息,请你求出 zyl 在拆信过程中最高的惊喜值和最终的惊喜值。
输入格式
输入共 n + 1 n+1 n+1 行。
第一行五个整数 n , x , y , a , b n,x,y,a,b n,x,y,a,b,含义如题所示。 接下来 n n n 行,每行三个整数
S , s , M S,s,M S,s,M。表示这封信的信封表面积,信纸面积和总质量,单位分别为平方厘米 、平方厘米、毫克。输出格式
输出共一行两个整数,第一个表示拆信过程中的最高惊喜值,第二个表示最终的惊喜值,二者之间使用空格隔开。
样例 #1
样例输入 #1
6 1 1 2 2 5 3 10 6 2 12 2 3 5 2 3 11 3 5 8 2 2 4
样例输出 #1
21 10
提示
样例 1 解释 惊喜值的变化如下表: | 信的序号 | 礼物重量 | 惊喜值增加 | 额外增加 | 是否折半 | 是否翻倍 | 惊喜值 | | :----------: | :----------: | :----------: | :----------: |
:----------: | :----------: | :----------: | | 1 | 2 2 2 | 2 2 2 | 0 0 0 | 否
| 否 | 2 2 2 | | 2 | 4 4 4 | 4 4 4 | 0 0 0 | 否 | 是 | 12 12 12 | | 3 | 0 0 0 | 0 0 0 |
0 0 0 | 否 | 否 | 12 12 12 | | 4 | 6 6 6 | 6 6 6 | 3 3 3 | 否 | 否 | 21 21 21 | | 5 | 0 0 0
| 0 0 0 | 0 0 0 | 否 | 否 | 21 21 21 | | 6 | 0 0 0 | 0 0 0 | 0 0 0 | 是 | 否 | 10 10 10 |最高的惊喜值为 21 21 21,最终的惊喜值为 10 10 10。
数据规模与约定
对于 40 % 40\% 40% 的数据, n ≤ 1000 n\leq 1000 n≤1000,任意时刻的惊喜值不会超过 1 0 9 10^{9} 109。 对于另外 20 % 20\% 20%
的数据, a = b = n a=b=n a=b=n。 对于 100 % 100\% 100% 的数据, 1 ≤ a , b ≤ n ≤ 1 0 6 1\leq a,b\leq n\leq 10^{6} 1≤a,b≤n≤106, 1 ≤ x , y ≤ 20 1\leq x,y\leq 20 1≤x,y≤20, 1 ≤ S , s ≤ 500 1\leq S,s\leq 500 1≤S,s≤500, x × S + y × s ≤ M ≤ 1 0 5 x\times S+y\times s\leq M\leq 10^{5} x×S+y×s≤M≤105,任意时刻的惊喜值不会超过 1 0 18 10^{18} 1018。
一句话,简简单单模拟
#include
using namespace std;
int n, x, y, a, b, e, w, l, r, q;
long long maxd, j;
int main() {
cin >> n >> x >> y >> a >> b;
for (int i = 1; i <= n; i++) {
cin >> l >> q >> w;
if (l * x + q * y == w) {
e++;
if (e >= b) j /= 2;
r = 0;
} else {
r++;
if (e >= b) {
e = 0;
continue;
}
e = 0;
if (w > (l * x + q * y) * 2)
j += ceil(1.5 * ( w - l * x - q * y ));
else j += w - l * x - q * y ;
if (r >= a) j *= 2;
}
maxd = max(j, maxd);
// cout << maxd << " " << j << endl;
}
cout << maxd << " " << j;
}
根本不要这一段好吧
if (e >= b) {
e = 0;
continue;
}
一句开头是句号,表示管前面一段。若是逗号,表示只针对这一句。
#include
using namespace std;
int n, x, y, a, b, e, w, l, r, q;
long long maxd, j;
int main() {
cin >> n >> x >> y >> a >> b;
for (int i = 1; i <= n; i++) {
cin >> l >> q >> w;
if (l * x + q * y == w) {
e++;
if (e >= b) j /= 2;
r = 0;
} else {
r++;
e = 0;
if (w > (l * x + q * y) * 2)
j += ceil(1.5 * ( w - l * x - q * y ));
else j += w - l * x - q * y ;
if (r >= a) j *= 2;
}
maxd = max(j, maxd);
// cout << maxd << " " << j << endl;
}
cout << maxd << " " << j;
}
题目背景
破碎的纸条记录教室的点滴,跳动的字体奏响青春的乐章,纸条是调皮的学生们在自习课的传声筒,上面写的事,平平淡淡,但离开校园后,它们又弥足珍贵,那不足半巴掌的大的纸条拼凑成了我们的青春。
zyl 有时也会传纸条,内容也很平淡,不过他把一些纸条贴在他的日记本上了,现在翻一翻里面的内容,感觉很欣慰……因为之前一切都是那么美好。题目描述
zyl 桌上有 n n n 张纸条(编号 1 ∼ n 1\sim n 1∼n),他要把这些纸条按被写下的时间的前后顺序排好,但是纸条上不会有日期,zyl
需要自己判断。zyl
可以根据纸条内容的连贯性来确定紧跟在一张纸条之后纸条有哪些。同时,他可以通过纸条的破损程度判断内容不连贯的纸条的时间先后顺序。显然,对于一段连贯内容的最后一张纸条,紧跟在它后面的纸条只能通过破损程度来判断。现在,你会收到按以下规则给出的,每张纸条的信息:
首先,你会得知在这一段连贯内容中紧跟在这张纸条后面的纸条的数量 m m m。
其次,按照时间前后依次告诉你这些纸条的编号。
如果没有「连贯内容中紧跟在后面的纸条」(即在连贯内容的最后一张, m = 0 m = 0 m=0),则会按照破损程度给出紧跟它的下一张纸条的编号,如果没有「按照破损程度紧跟它的下一张纸条」,你会得到一个 − 1 -1 −1 信号。
如果对于这一部分理解有困难,可以参照「输入格式」及「样例组」进行理解。
请你帮助 zyl 将纸条排序,并将这 n n n 张纸条按时间顺序排序后的编号输出。
输入格式
输入共 n + 1 n+1 n+1 行。
第一行一个整数 n n n,表示纸条的张数。
第 2 ∼ n + 1 2\sim n+1 2∼n+1 行,第 i + 1 i+1 i+1 行具体内容如下: 第一个整数 m m m,表示在连贯内容内 i i i 号纸条之后有多少张纸条。
- 如果 m > 0 m>0 m>0,则接下来 m m m 个整数,表示按照时间前后紧跟在 i i i 号纸条后的纸条编号。
- 如果 m = 0 m = 0 m=0,接下来一个整数,表示按照纸条的破损程度,紧跟在 i i i 号纸条后面的纸条编号。如果其后没有纸条,则该整数为 − 1 -1 −1。
输出格式
输出共一行 n n n 个整数,表示按时间先后排好序后纸条的编号。
样例 #1
样例输入 #1
5 1 3 2 1 3 0 5 0 -1 1 4
样例输出 #1
2 1 3 5 4
提示
样例 1 解释
纸条 2 , 1 , 3 2,1,3 2,1,3 是内容连贯的纸条,纸条 5 , 4 5,4 5,4 是另一组内容连贯的纸条。
数据规模与约定
对于 20 % 20\% 20% 的数据, n ≤ 5 n\leq 5 n≤5。 对于 100 % 100\% 100% 的数据, 0 ≤ m < n ≤ 2 × 1 0 3 0\leq m
0≤m<n≤2×103 。
主观认为这是本次比赛最难的一道题,关键在于,它不仅仅是那种一个劲儿模拟暴力,没有思维含量,这道题我觉得还是要用一些链表的思想比较方便。
我们在输入时,只需要看每一行的第二的数,代表这个元素的下一个元素,至于它在后面是啥,可以暂时不用知道。
然后,用一个vector存储顺序,首先找到-1的元素,然后记录它的编号,在找到指向这一编号的元素,记录他的位置,以此类推,即可。
#include
using namespace std;
int o[2005], n, l, h, p;
vector<int>k;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> l >> h;
o[i] = h;
for (int j = 1; j <= l - 1; j++)
cin >> h;
}
p = -1;
for (int j = 1; j <= n; j++)
for (int i = 1; i <= n; i++)
if (o[i] == p) k.push_back(i), p = i;
for (int i = n - 1; i >= 0; i--)cout << k[i] << " ";
}
题目背景
棋
秋风徐徐,烈日直挂。窗边,你我相对而坐。初秋,起笔。谁知,一番欢旅暗中起。
春风暖暖,夕阳西下。桌旁,你我相伴而笑。暮春,落笔。奈何!半层薄纱难除去。zyl 珍藏了与她的最后几把棋,而最后一把棋做为离别礼物留给了她,并附上这首词… zyl
和她刚认识就是通过一把棋,而且,他们一起干过最多的是就是下棋了。zyl 每天都期待着能和她下一把棋,因为那是 zyl
最快乐的时光——他们都喜欢下棋,有时甚至能放学后还一起下棋,下到很晚…… zyl
最喜欢中国象棋,她最喜欢国际象棋。不过,他们下的最多的是五子棋,因为五子棋简单易懂,思路清晰,却又灵活多变,技巧丰富。
他们下的第一把棋就是五子棋,最后一把棋也是五子棋……这相隔了整整 188 天…… 下棋时,时常会忘记了,谁该落子。 现在 zyl
从包里翻出了珍藏的格子纸,这上面是他和她的最后几局棋。他想要知道,这些棋局,是否已结束于时间长河中;这些棋局中,谁又是最后的胜者。题目描述
zyl 和「她」在 n × m n\times m n×m 的格子纸上下五子棋。「她」总是先手。
现在你会得知以下信息:
- 格子纸的大小 n , m n, m n,m,代表棋盘共 n n n 行 m m m 列。
- n n n 个仅由字符
~
、*
、$
构成的长度为 m m m 的字符串(即 n × m n \times m n×m 个字符)。对于第 i i i 个字符串的第 j j j 个字符,~
表示第 i i i 行第 j j j 列的格子是空的,*
表示「她」已经在这一格落下棋子,$
表示
zyl 已经在这一格落下棋子。类似于五子棋的基本规则,一局棋局由「先手」开始,双方轮流落子。如果有同一行,同一列,或者同一 45 ° 45\degree 45°
斜对角线有同一方的连续五个棋子,那这一方便是胜者。现在,请你以以下方式判断当前的棋局:如果已有一方获胜,请你判断是哪一方获胜。否则,请你判断当前轮到哪一方落子。
输入格式
输入共 n + 1 n + 1 n+1 行。
第一行两个整数 n , m n,m n,m,表示格子纸的大小。 接下来 n n n 行,每行一个长度为 m m m 的,仅由字符
~
、*
、$
组成的字符串,代表棋局的情况。输出格式
输出共一行一个字符串或一个字符,表示棋局的情况。
- 如果已有一方获胜,输出一个字符串
Pleasing!
或zylwins!
。Pleasing!
表示「她」获胜,zylwins!
表示 zyl 获胜。- 否则,输出一个字符
W
或Z
。W
表示当前轮到「她」落子,Z
表示轮到 zyl 落子。样例 #1
样例输入 #1
***~~ ~$*~~ ~~*~$ $$*$~ ``` ### 样例输出 #1 ```Pleasing! ``` ## 提示 ### 样例 1 解释 在第三列有连续的五个 `*`,所以「她」获胜了。 ### 数据规模与约定 本题采用**捆绑测试**。你只有通过一个子任务里的所有测试点,才能得到这个子任务的得分。 对于 $100\%$ 的数据, $5\leq n,m \leq 30$,字符串仅由 `~`、`*`、`$` 组成,而且不会出现任意同一行,同一列或是同一 $45\degree$ 斜对角线上有连续 6 个或以上连续且相同的 `*` 或 `$`,并且最多只有一条连续的 $5$ 个 `*` 或 `$`。 `*` 的总数不小于 `$` 的总数,且至多比 `$` 的总数大 $1$。保证输入的字符串至少存在一个字符 `~`。 | 子任务编号 | 分值占比 | 约束条件 | | :-: | :-: | :-: | | 1 | $40\%$ | 保证没有任何一方获胜 | | 2 | $60\%$ | 无特殊约束条件 | ### 小彩蛋 对于后 $40\%$ 的数据,给出的棋局对应 zyl 珍藏的那四把棋。
直接暴力,注意边界:x<=n-4,y<=m-4,暴力直接AC。
#include
using namespace std;
int n, m, a1, a2;
char a[35][35];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
if (a[i][j] == '*')a1++;
if (a[i][j] == '$')a2++;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if(a[i][j]=='~')continue;
if (j<=m-4&&(a[i][j] == a[i][j + 1] && a[i][j + 1] == a[i][j + 2] && a[i][j + 2]==a[i][j+3] && a[i][j+3]==a[i][j+4])) {
if (a[i][j] == '*') {
cout << "Pleasing!";
return 0;
}
if (a[i][j] == '$') {
cout << "zylwins!";
return 0;
}
}
if (i<=n-4&&(a[i][j] == a[i + 1][j] && a[i + 1][j] == a[i + 2][j] && a[i+2][j]==a[i+3][j] && a[i+3][j]== a[i + 4][j])) {
if (a[i][j] == '*') {
cout << "Pleasing!";
return 0;
}
if (a[i][j] == '$') {
cout << "zylwins!";
return 0;
}
}
if (i<=n-4&&j<=m-4&&(a[i][j] == a[i + 1][j + 1] &&a[i+1][j+1]== a[i + 2][j + 2] && a[i + 2][j + 2] == a[i + 3][j + 3] && a[i + 3][j + 3] == a[i + 4][j + 4])) {
if (a[i][j] == '*') {
cout << "Pleasing!";
return 0;
}
if (a[i][j] == '$') {
cout << "zylwins!";
return 0;
}
}
}
}
if (a1 == a2) cout << 'W';
else cout << "Z";
}
歌曲是拉近一切的绳索,是传递快乐的万花筒,是减轻寂寞的良方!
歌曲,美妙的语言!
对 zyl 来讲,歌曲十分特殊。
新班级的同学他几乎不认识。不过,大家都知道他的名字,因为他每天会在晚饭时间给大家唱歌,而同学们每天都等候着他的出场,因为他们会因此收获许多快乐。
一个特殊的节日,zyl 举办了一场演唱会,他想要规划一下演唱会的曲目。
根据同学的要求,他要从之前唱过的 n n n 首歌(编号 1 ∼ n 1\sim n 1∼n)中选出 m m m 首加入演唱会歌单。
选择的规则很简单,班上有 a a a 名学生(不包括 zyl),学号为 1 ∼ a 1\sim a 1∼a。zyl 会按照学号统计每位同学从每首歌中得到的快乐值,记为 h i , j h_{i,j} hi,j。一首歌的「欢乐度」是它所给予其他所有同学的「快乐值」总和。
巧妙的是,由于歌曲风格迥异,同一个学生一定会从不同的歌中会收获不同的快乐值,且不会有任何两首歌的欢乐度相同。
zyl 选出欢乐度最高的 m m m 首歌,并将它们按欢乐度从大到小排好序。
但 zyl 注意到了她的快乐值…
无论如何,zyl 一定会把她最喜欢的歌放进歌单(zyl 会认为她从哪首歌得到的快乐值最高,她最喜欢的就是哪首歌)!
如果她最喜欢的歌之前已经在歌单中,那么 zyl 会把这首歌提到歌单的第一个位置(即,仅将该歌曲的位置变为第一位,其余歌曲的相对位置不变);但如果不在,zyl 则会把已经选择好的歌单里的最后一首歌给删掉。然后把她最喜欢的曲目放在歌单的最后。
现在 zyl 将统计的快乐值数据和她的学号交给你,请你帮他列出演唱会的歌单。
输入共 a + 1 a + 1 a+1 行。
第一行共四个整数 n , m , a , b n, m, a, b n,m,a,b,分别代表待选的歌的数量,需要选出的歌的数量,班上的人数,她的学号。
接下来 a a a 行,每行 n n n 个整数,第 i + 1 i+1 i+1 行第 j j j 个数代表学号为 i i i 的学生从第 j j j 首歌收获的快乐值 h i , j h_{i,j} hi,j。
输出共一行用空格隔开的 m m m 个整数,依次代表演唱会的歌单上的歌的编号。
4 2 3 2
2 4 3 1
1 2 3 4
2 3 4 1
3 4
按照欢乐度排序后靠前的两道是 3 , 2 3, 2 3,2,但由于她最喜欢的歌是 4 4 4,不在歌单里,于是将 2 2 2 从歌单里删除,之后将 4 4 4 放在最后。最后的歌单为 3 , 4 3, 4 3,4。
对于 100 % 100\% 100% 的数据, 1 ≤ m ≤ n ≤ 1 0 5 1\leq m \leq n \leq 10^5 1≤m≤n≤105, 1 ≤ b ≤ a ≤ 100 1\leq b \leq a\leq 100 1≤b≤a≤100。 0 ≤ h i , j ≤ 1 0 6 0\leq h_{i,j}\leq 10^6 0≤hi,j≤106。
数据保证不存在 j ≠ k j \neq k j=k,使得存在 i ∈ [ 1 , n ] i \in [1, n] i∈[1,n] 且 h i , j = h i , k h_{i,j} = h_{i,k} hi,j=hi,k。数据还保证不存在 j ≠ k j \neq k j=k,使得 ∑ i = 1 n h j , i = ∑ i = 1 n h j , k \sum_{i = 1}^n h_{j,i} = \sum_{i = 1}^n h_{j, k} ∑i=1nhj,i=∑i=1nhj,k。
测试点编号 | n n n | m m m | a a a | h i , j h_{i,j} hi,j |
---|---|---|---|---|
1 ∼ 2 1 \sim 2 1∼2 | ≤ 5 \leq5 ≤5 | = 1 =1 =1 | ≤ 5 \leq5 ≤5 | ≤ 10000 \leq 10000 ≤10000 |
3 ∼ 4 3 \sim 4 3∼4 | ≤ 1000 \leq1000 ≤1000 | = n =n =n | ≤ 100 \leq100 ≤100 | ≤ 10000 \leq 10000 ≤10000 |
5 ∼ 6 5 \sim 6 5∼6 | ≤ 1000 \leq 1000 ≤1000 | ≤ 1000 \leq 1000 ≤1000 | = 1 =1 =1 | ≤ 10000 \leq 10000 ≤10000 |
7 ∼ 9 7 \sim 9 7∼9 | ≤ 1000 \leq1000 ≤1000 | ≤ 1000 \leq1000 ≤1000 | ≤ 100 \leq100 ≤100 | ≤ 10000 \leq 10000 ≤10000 |
10 10 10 | ≤ 1 0 5 \leq 10^5 ≤105 | ≤ 1 0 5 \leq 10^5 ≤105 | ≤ 100 \leq 100 ≤100 | ≤ 1 0 6 \leq 10^6 ≤106 |
就是模拟
先读入,用一个结构体来存储它的值和编号,在进行一次排序(需要自己写cmp),看看她的最爱在不在现在名单里,在的话,把她的歌值赋值为INT_MAX,若不在,赋值为现在卡线上的歌值加一。然后再进行一次排序,输出即可。
#include
using namespace std;
bool k;
int n,m,a,b,l[103][100005],p[100005],ml,o,u;
struct node{
int o,t;
}r[100005];
bool cmp(node x, node y){return x.o>y.o;}
int main(){
cin >> n >> m >> a >> b;
for(int i = 1; i <= a;i++){
for(int j = 1; j <= n; j++)
cin >> l[i][j],r[j].o+=l[i][j];
}
for(int i = 1; i <= n; i++) r[i].t=i;
for(int i = 1; i <= n; i++){
if(l[b][i]>ml)ml=l[b][i],o=i;
}
sort(r+1,r+1+n,cmp);
for(int i = 1; i <= m; i++)
if(r[i].t==o) r[i].o=INT_MAX,k=1;
if(!k){
for(int i = 1; i <= n; i++)
if(r[i].t==o) r[i].o=r[m].o+1;
}
sort(r+1,r+1+n,cmp);
for(int i = 1; i <= m; i++) cout << r[i].t << " ";
}
本以为它是专门卡了个模拟不过,结果是我没加读入优化,以前还有点瞧不起这个优化,没想到关键时刻挺有用的。
#include
using namespace std;
bool k;
long long n,m,a,b,l[103][100005],p[100005],ml,o,u;
struct node{
int o,t;
}r[100005];
bool cmp(node x, node y){return x.o>y.o;}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin >> n >> m >> a >> b;
for(int i = 1; i <= a;i++){
for(int j = 1; j <= n; j++)
cin >> l[i][j],r[j].o+=l[i][j];
}
for(int i = 1; i <= n; i++) r[i].t=i;
for(int i = 1; i <= n; i++){
if(l[b][i]>ml)ml=l[b][i],o=i;
}
sort(r+1,r+1+n,cmp);
for(int i = 1; i <= m; i++)
if(r[i].t==o) r[i].o=INT_MAX,k=1;
if(!k){
for(int i = 1; i <= n; i++)
if(r[i].t==o) r[i].o=r[m].o+1;
}
sort(r+1,r+1+n,cmp);
for(int i = 1; i <= m; i++) cout << r[i].t << " ";
}
请注意本题得分不随时间流逝而递减。
请注意本题得分不随时间流逝而递减。
请注意本题得分不随时间流逝而递减。
这是一道 hack 题。在本题目中,你将得到两个问题和两个解决对应问题的代码,但是给出的代码不能对于某些输入给出正确的输出。不能给出正确的输出的情况包括:
对于这一问题,你需要提交一份符合要求的输入数据,使得给定的代码不能给出正确的输出。你可以直接使用『提交答案』功能,也可以提交一份以任何语言写成的数据生成器。
提示:如果你使用提交答案功能,请在提交其他题目时记得将语言改回你所使用的语言。
以下给出两个问题的题目描述:
给出整数 a , b , c a, b,c a,b,c,求 ⌈ a b − c ⌉ \left\lceil\dfrac {a}{b - c} \right\rceil ⌈b−ca⌉ 的值,其中 ⌈ x ⌉ \left\lceil x \right\rceil ⌈x⌉ 表示不小于 x x x 的最小整数。
std::cerr
是一个输出到标准错误流的输出工具。如果你运行如下程序:
#include
int main() {
std::cerr << "Hello Luogu!" << std::endl;
}
你会发现有 Hello Luogu! \texttt{Hello Luogu!} Hello Luogu! 被打印在了命令行 /cmd 中;但是,如果你在 main
函数开头加入 freopen("text.txt", "w", stdout)
,再运行这个程序,然后打开 text.txt
,会发现文件是空的,而 Hello Luogu! \texttt{Hello Luogu!} Hello Luogu! 仍然被打印到了命令行 /cmd 中。
由此,std::cerr
在算法竞赛中有了一个重要应用:使用 std::cerr
输出中间变量,变量会被打印到屏幕上,但却不会被打印到输出文件/标准输出中。同时,std::cerr
有刷新缓冲区的作用。以往关闭流同步代码一旦产生 Runtime Error,在这之前被打印到 stdout 的内容如果仍在缓冲区,则不会被输出,而使用 std::cerr
则不会有这个问题,因为每次完成输出后都会将缓冲区内容直接刷新到标准错误流中。
例如,你可以尝试在本地运行如下代码:
#include
int main() {
std::ios::sync_with_stdio(false);
std::cout << "Hello Luogu!\n";
int x = *((int*)0);
}
对于大多数机器,屏幕上什么都不会打印,应用程序就会异常终止,这种情况是不利于调试的,因为无法二分出导致程序终止语句是哪一条。但是,如果你将上文中的 std::cout
换成 std::cerr
再尝试运行这一程序,就会发现在程序异常终止前, Hello Luogu! \texttt{Hello Luogu!} Hello Luogu! 被打印到了屏幕上。需要注意的是,刷新缓冲区是一件速度很慢的事情,如果刷新次数太多,会导致程序超时。
在刚结束的 ICPC 山东省赛中,扶苏试图使用 std::cerr
来完成对 K 题的调试,但是在四小时 59 分提交的代码中,扶苏本已经写出了正确的代码,但却忘记了删除 std::cerr
的调试语句,虽然这不会导致她向选手输出中输出额外信息,但因为刷新缓冲区次数过多,她本次提交被判定为 TIME LIMIT
,与省赛冠军失之交臂。
(计算可得,如果第四发 K 题的 attempt 通过,『四小时下班』将以 8 8 8 分钟罚时的优势绝杀夺冠)
因此,对于一个字符串,她觉得如果这个字符串含有 std::cerr
作为子串,则她觉得这个字符串『不太行』,否则她觉得这个字符串『非常行』。
给定 T T T 个字符串,请你判断它们是不是『不太行』。
输入只有一行三个整数,依次表示 a a a, b b b, c c c。
第一行是一个整数,表示输入字符串个数 T T T。
接下来 T T T 行,每行一个字符串,表示需要你判断的字符串。
在问题 2 2 2 中,输入不能有行末空格。但可以有文末回车。
输出一行一个整数表示答案。
输出一行一个整数,表示『不太行』的字符串数量。
9 8 5
3
3
std::cerr
std::cerr<<"HelloLuogu!";
std::cout<<"HelloLuogu!";
2
两个样例分别对应两个问题的样例输入输出。
如果你直接采用『提交答案』的方式,请分别将两个输入数据命名为 1.in
、2.in
,并打成 zip 压缩包进行提交;
如果你采用提交数据生成器的方式,你的生成器可以从标准输入读入一个整数 x x x,满足 1 ≤ x ≤ 2 1 \leq x \leq 2 1≤x≤2,表示该测试点对应的问题编号,然后输出对应的输入数据。
显然,你的程序不应该读入『输入格式』里提到的任何内容(而应该构造它们),也不应该输出『样例输出』里提到的任何内容(而是只输出你构造的输入数据)。你不应该使用样例测试你的程序,这只是对两个问题的样例说明。
你给出的数据必须满足如下要求:
你需要 hack 如下的代码:
#include
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
int d = b - c;
cout << ((a + d - 1) / d) << endl;
}
#include
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
std::string s;
int ans = 0, cur = 0;
for (std::cin >> T; T; --T) {
std::cin >> s;
++cur;
if (s.find("std::cerr") != std::string::npos) {
std::cerr << cur << '\n';
++ans;
}
}
std::cout << ans << std::endl;
}
目标代码的编译选项为 -std=c++14 -fno-asm -O2
。编译器为洛谷提供的 g++。你可以在『在线 IDE』中选择 C++14 语言来获得完全相同的编译环境。
你给出的数据必须完全符合『数据规模要求』,否则将得到 Unaccepted 的结果。
程序每执行若干条指令,我们会检测一遍程序的运行时间。我们保证两次检测之间的指令条数是一个输入规模无关的量,也即每执行 O ( 1 ) O(1) O(1) 条指令会进行一次检测。且两次检测之间的指令条数不会太多,一般不超过 100 100 100 条 C++ 语句。
如果程序的运行时间超过 500 ms 500 \text{ms} 500ms,则判定为程序运行超时,返回 accepted 结果。
如果程序在规定的时间内结束且给出了一个输出,我们会比较这个输出和完全正确的输出,如果二者不同,则判定为 hack 成功,返回 accepted 结果。
我们会在每次显式的调用数组元素前判断数组下标是否超过数组范围,如果超过,则判定为 hack 成功,返回 accepted 结果。
这就是说,如果你希望通过未定义行为进行 hack,只能对显式的调用数组元素的行为进行 hack。
这是一份可以帮你理解你需要输出的内容的样例程序,但它不能给出正确的 hack 数据。直接提交此程序不会得分。
#include
using namespace std;
int main() {
int taskId;
cin >> taskId;
if (taskId == 1) {
cout << "" <<endl;
} else if (taskId == 2) {
cout << "" << endl;
} else { // 这个 else 不会被执行
cout << "Stupid Fusu!" << endl;
}
}
如果你使用『提交答案』功能,请务必保证打开压缩包后能且仅能直接看到两个 .in
文件。这就是说,文件结构必须是:
ans.zip
|---1.in
|---2.in
两个文件不应该被额外的文件夹包含,即文件结构不能是:
ans.zip
|---ans(folder)
|---1.in
|---2.in
如果 hack 成功,对应测试点的信息为 accepted。如果返回其他信息,说明程序本身有误。
例如,如果返回 TLE,不代表成功的将对应程序 hack 至超时,而是表示数据生成器本身运行超时,测试点不得分。
特别的,返回 UKE 结果可能是数据不合法(有多余内容、缺少内容或数据范围不符合要求)。
第一个问,审视一遍程序不难发现它没考虑到负数情况。
第二个问,诶,我就纳了闷了,这个数据难道没把它hack到吗
1
sssstd::cerr
它输出了2个1好不好,要求只输出一行一个整数。
#include
using namespace std;
int main() {
int taskId;
cin >> taskId;
if (taskId == 1) {
cout << "9 5 8" <<endl;
} else if (taskId == 2) {
cout << "1"<<endl<<"sssstd::cerr" << endl;
} else { // 这个 else 不会被执行
cout << "Stupid Fusu!" << endl;
}
}
#include
using namespace std;
int main() {
int taskId;
cin >> taskId;
if (taskId == 1) {
cout << "9 5 8" <<endl;
} else if (taskId == 2) {
cout << "222222" << endl;
for(int i = 1; i <= 222222; i++) cout << "std::cerr\n";
} else { // 这个 else 不会被执行
cout << "Stupid Fusu!" << endl;
}
}