码迷,mamicode.com
首页 > 其他好文 > 详细

CPPU程序设计训练营清明天梯模拟赛题解

时间:2020-04-04 22:47:46      阅读:89      评论:0      收藏:0      [点我收藏+]

标签:注意   从后往前   第一步   namespace   不能   turn   block   过程   int   

感谢大家今天来做题

比赛地址:http://202.206.177.79/contest/8

由于博主比较菜,没做完所有题目,这里暂时仅提供前两部分的题解。

为了节约篇幅,题目及数据描述不再赘述,如有需求,请移步OJ查看。

感谢大家的辛苦付出,但是从这次比赛的结果来看,前行之路还非常非常漫长呐。

我寂寞的时候,会害怕踏出第一步。不会想到要去做什么事,所以,可能没有发觉很多很多的东西吧。——《夏目友人帐》

第一阶段

L1-1 天梯赛座位分配 (20分)

通过率:2.56% \(\;\;\) 通过人数:1

模拟题,整体难度大于后面几道题。此外对输出格式要求极为严苛,比较坑。

比较优秀的特点是数据范围不大,所以可以直接用 \(O(10*N*M)\) 的时间模拟编号过程(细节见代码)。

在每个学校都还有余量时,相临两位选手的座位号是以 \(N\) 为公差的等差数列,

但一旦有一些学校满编了,我们要在模拟的过程中跳过该校(要注意下 \(n\) 的后继是 \(1\)),

如果检测到当前只有一所学校有余量,需要隔座编号,我的代码使用了 \(add\) 累计隔座数量。

细心的同学可以发现输出描述有一句:行首尾不得有多余空格

这就比较魔性了,一般的题目行尾是可以有空格的,所以输出时格外注意格式(我第一次交就没看到这个)。

代码如下:

#include <bits/stdc++.h>
#define MAXN 107
using namespace std;
int n,pos,add,tot,p[MAXN];
vector<int> v[MAXN];
int main() {
	scanf("%d",&n);
	for (int i=1;i<=n;i++) {
		scanf("%d",&p[i]),p[i]*=10;
		tot+=p[i];
	}
	for (int i=1;i<=tot;i++) {
		int pre=pos; 
		pos=(pos==n)?1:pos+1;
		while ((int)v[pos].size()==p[pos])
			pos=(pos==n)?1:pos+1;
		if (pre!=pos) v[pos].push_back(i); //正常编号
		else v[pos].push_back(i+(++add)); //仅剩一所学校有余量,要隔座
	}
	for (int i=1;i<=n;i++) {
		printf("#%d\n",i);
		for (int j=0;j<p[i];j++) {
			printf("%d",v[i][j]);
			putchar((j+1)%10?‘ ‘:‘\n‘); //行尾不能有空格
		}
	}
	return 0;
} 

L1-2 倒数第N个字符串 (15分)

通过率:36.84% \(\;\;\) 通过人数:14

模拟题,用C++写应该比较简单,我头铁用Python搞了半天。

模拟的过程和数学上的加减法的进位/借位比较像,以从倒着数为例:

zba 的前驱是 zaz ,模拟的操作就是从后往前找到第一个不为a的字母,

然后把它之后的的所有a(如果有的话)改成z,计数器同时工作即可。

代码如下:

import math

def main():
    l, n = input().split()
    l = int(l); n = int(n)
    ans = ‘z‘ * l
    for i in range(n-1):
        pos = l - 1
        while ans[pos]==‘a‘: pos-=1
        ans = ans[:pos] + chr(ord(ans[pos])-1) + (l-pos-1)*‘z‘
    print(ans)
    
if __name__ == "__main__":
    main()

L1-3 倒数第N个字符串 (15分)

通过率:73.91% \(\;\;\) 通过人数:34

考察了最简单的数据处理以及读入输出,注意一下整形到浮点形的运算语法以及保留小数即可。

def main():
    a, b = input().split()
    ans = float(a)*float(b)/10
    print("%.2f" %ans)

if __name__ == "__main__":
    main()

L1-4 2018我们要赢 (5分)

通过率:63.46% \(\;\;\) 通过人数:33

这题通过率和通过人数还不如上一题,咋肥事啊。

直接输出!你敢送分我敢拿!

def main():
    print("2018")
    print("wo3 men2 yao4 ying2 !")

if __name__ == "__main__":
    main()

L1-5 电子汪 (10分)

通过率:59.62% \(\;\;\) 通过人数:31

考察了作为单身狗的口算水平,也没什么好说的。

def main():
    a, b = input().split()
    for i in range(int(a)+int(b)):
        print("Wang!", end=‘‘)
        
if __name__ == "__main__":
    main()

L1-6 福到了 (15分)

通过率:18.97% \(\;\;\) 通过人数:11

技术图片

模拟题,细节要求比较多。

题目所要求的倒置指的是整图旋转 \(180°\),满足的性质是 \(map[i][j] -> map[n-i+1][n-j+1]\)

简单观察一下样例可以知道,把列倒过来,再把行倒过来就倒置了。

判断是否输出bu yong dao le可以使用上面那个性质,如果每一个坐标都满足就要输出。

def main():
    k, n = input().split()
    n = int(n)
    l = []; r = []
    for i in range(n):
        opt = input().replace(‘@‘, k).ljust(n, ‘ ‘)
        l.append(opt)
    for i in range(n-1, -1, -1):
        t = list(l[i]).reverse()
        r.append(l[i][::-1])
    fl = 0
    for i in range(n):
        if l[i] != r[i]:
            fl = 1; break
    if fl == 0: print("bu yong dao le")
    for i in range(n):
        for j in range(len(r[i])):
            if r[i][j]!=‘ ‘: print(k, end=‘‘)
            else: print(‘ ‘, end=‘‘)
        print(‘\n‘, end=‘‘)
        
if __name__ == "__main__":
    main()

CPPU程序设计训练营清明天梯模拟赛题解

标签:注意   从后往前   第一步   namespace   不能   turn   block   过程   int   

原文地址:https://www.cnblogs.com/zhwer/p/12634446.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!