1052 卖个萌 (20 分) PTA服务器上Python3是无解的

1052 卖个萌 (20 分)

萌萌哒表情符号通常由“手”、“眼”、“口”三个主要部分组成。简单起见,我们假设一个表情符号是按下列格式输出的:

[左手]([左眼][口][右眼])[右手]

现给出可选用的符号集合,请你按用户的要求输出表情。

输入格式:

输入首先在前三行顺序对应给出手、眼、口的可选符号集。每个符号括在一对方括号 []内。题目保证每个集合都至少有一个符号,并不超过 10 个符号;每个符号包含 1 到 4 个非空字符。

之后一行给出一个正整数 K,为用户请求的个数。随后 K 行,每行给出一个用户的符号选择,顺序为左手、左眼、口、右眼、右手——这里只给出符号在相应集合中的序号(从 1 开始),数字间以空格分隔。

输出格式:

对每个用户请求,在一行中输出生成的表情。若用户选择的序号不存在,则输出 Are you kidding me? @\/@

输入样例:

[╮][╭][o][~\][/~]  [<][>]
 [╯][╰][^][-][=][>][<][@][⊙]
[Д][▽][_][ε][^]  ...
4
1 1 2 2 2
6 8 1 5 5
3 3 4 3 3
2 10 3 9 3

输出样例:

╮(╯▽╰)╭
<(@Д=)/~
o(^ε^)o
Are you kidding me? @\/@

 说明:

    本文用于说明PTA服务器执行Python3版本的提交程序的“漏洞”,测试时间为2019年6月25日,故日后此漏洞若修复,则可以忽略本文,并请发现者回复一声。

分析:

    因为我在练习Python,所以这道题我也是用Python3来解决。没想到,无论如何尝试我都无法得分。

    此题若作为算法题非常简单:

  1. 先将[]括号括起来的手眼口符号表转化为数组(列表、元组……),方便索引
  2. 按照题目要求输出即可,注意“符号在相应集合中的序号(从 1 开始)”。

Python 初稿:(本地IDE可以正常通过)

def Input():    #每个符号括在一对方括号 []内
    return tuple(map(lambda s:(s.split(']'))[0] ,input().split('[')))
T=(Input(),Input(),Input())	#T[*][0] 是不使用的字符串,恰好迎合了指定表情字符序号从1开始
for i in range(int(input())):
    A=[int(a) for a in input().split()]   #序号(从 1 开始)
    try:print("{}({}{}{}){}".format(T[0][A[0]],T[1][A[1]],T[2][A[2]],T[1][A[3]],T[0][A[4]]))
    except: print('Are you kidding me? @\/@')

简直精简极了!代码仅有7行! 然而提交上去竟然0分,原因是“返回非零”!


查找原因:

    通过try——excep——while True:的方法让服务器返回“运行超时”来判断。

    一开始以为是Input():方法挤在一行过于精简,其中某一函数无法被服务器IDE解释导致错误。我换了另一种处理方法,发现此题用Python3是“无解的”!因为错误的原因竟然是“input()”。如下代码,在本地IDE可以正常过样例!但是在 s1=input() 处,无法try,转到except的死循环中。

'''
提交时间	状态	分数	题目	编译器	耗时	用户
2019/6/25 16:53:08	
运行超时
0	1052	Python (python 3)	--	玮智能
测试点	结果	耗时	内存
0	运行超时	--	0 KB
1	运行超时	--	0 KB
2	运行超时	--	0 KB
'''

def Input(s):    #每个符号括在一对方括号 []内
    T=[]
    while True:
        try:
            L,R=s.index('['),s.index(']',1)
            T.append(s[L+1:R])
            s=s[R+1:]
        except:
            return tuple(T)

def main():
    try:	#提交结果:运行超时,说明下面三行input()出现超时。到底什么梗,连输入都不让输入
        s1=input()
        s2=input()
        s3=input()
    except:
        while True:a=1
    T=(Input(s1),Input(s2),Input(s3))
    #print(T)
    for i in range(int(input())):
        A=[int(a)-1 for a in input().split()]   #序号(从 1 开始)
        try:print("{}({}{}{}){}".format(T[0][A[0]],T[1][A[1]],T[2][A[2]],T[1][A[3]],T[0][A[4]]))
        except: print('Are you kidding me? @\/@')
    #print('OK')

if __name__=="__main__":
    main()

为了证实确实是input() 的错误,做了对照实验,代码如下:

'''
提交时间	状态	分数	题目	编译器	耗时	用户
2019/6/25 17:01:46	
非零返回
0	1052	Python (python 3)	31 ms	玮智能
测试点	结果	耗时	内存
0	非零返回	23 ms	3316 KB
1	非零返回	23 ms	3228 KB
2	非零返回	31 ms	3228 KB

'''
def Input(s):    #每个符号括在一对方括号 []内
    T=[]
    while True:
        try:
            L,R=s.index('['),s.index(']',1)
            T.append(s[L+1:R])
            s=s[R+1:]
        except:
            return tuple(T)

def main():
    s1=input()    #与前面代码的区别仅在 此三句放外面,而 T=....放try里面
    s2=input()
    s3=input()
    try:
        T=(Input(s1),Input(s2),Input(s3))
    except:
        while True:a=1
    #print(T)
    for i in range(int(input())):
        A=[int(a)-1 for a in input().split()]   #序号(从 1 开始)
        try:print("{}({}{}{}){}".format(T[0][A[0]],T[1][A[1]],T[2][A[2]],T[1][A[3]],T[0][A[4]]))
        except: print('Are you kidding me? @\/@')
    #print('OK')

if __name__=="__main__":
    main()

将input()放在外面,直接就中断程序并“返回非零”了。


可能的原因:

    样例输入含有非ASCII字符![╮][╭][o][~\][/~]  [<][>]……

    而PTA服务器的Python解释器无法正常读入这些字符,导致出错。所以这道题想用Python3 通过是“无解”的,除非官方修复此漏洞。


附C++可以AC的版本:(C语言的风格)

#include<stdio.h>
int main() {
//一、输入“卖萌”字符集
	char ch,charHEM[3][10][5];	//charHEM[0~2]分别是手、眼、口。并不超过10个符号;每个符号包含1到4个非空字符。
	int size[3] = { 0 };	//分别是手、眼、口,二维数组列数
	for (int i = 0; i < 3; ++i) {
		while ((ch = getchar()) != '\n') {//检索一行
			if ('[' == ch) {	//遇到“[”开始存入一个“卖萌”字符串
				scanf("%[^]]", charHEM[i][size[i]++]);	//格式化输出 %[^]] 表示以]结束的字符串
			}
		}
	}
//二、用户指定序号,并输出
	const int iHEM[5] = { 0,1,2,1,0 };	//输出顺序 手、眼、口、眼、手
	int N; scanf("%d", &N);
	for (int i = 0; i < N; ++i) {	//N行输入
		int index[5];
		bool illegal = false;		//序号是否非法
		for (int j = 0; j < 5; ++j) {	//每行必有5个数
			scanf("%d", index + j);		//输入序号 (1为第1个)
			if (index[j]<1 || index[j]> size[iHEM[j]])	//序号非法了!
				illegal = true;
		}
		if (illegal)
			puts("Are you kidding me? @\\/@");	//注意 “\”要写成“\\”
		else {
#define HEM(j)  &charHEM[ iHEM[j] ][ index[j]-1 ][0]	//注意序号 “1”表示第一个,即[0],故要index[j]-1
			printf("%s(%s%s%s)%s\n", HEM(0), HEM(1), HEM(2), HEM(3), HEM(4));
		}
	}
	getchar(); getchar();
	return 0;
}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值