与Store Credit和Reverse Words同一组的另一道题,T9 Spelling也解决了。
题目大概意思就是,手机的9格键盘,上面有26个字母,0表示空格。a字母只需要按一个2,b字母需要连续按2两次,就是22,要输入ab时,2和22之间需要有一段间隔,用空格表示,而要输入的空格是0,例如 i am ok,对应的是4026065。具体的可以看http://code.google.com/codejam/contest/351101/dashboard#s=p2
由于7和9对应的是4个字母,其它的是3个字母,字母与数字之间的映射表需要手动写了。这里主要问题就是映射怎么写?
如果是'a'->2,'b'->22,或者'a'->'2','b'->'22',那么如果是连续的ab输入呢?处理当前输入的时候需要与前一个输入比较,a与b相差1,c与d也是相差1,不能用这种方法;'2'和'22'的比较也不好做(或许可以,11倍,111倍,或者1/11,1/111),需要考虑其它的方法。
Python中有一个很有意思的地方,就是数字与字符串相乘,是把字符串拷贝几份。所以我们可以这样映射,'a'->('2',1),'b'->('2',2),那么用stat记录上一次的状态,与当前状态比较就很简单了,当前是cur = ('2',2),上一次状态stat='2',那么cur[0]==stat,需要在之间加空格,而连按两次2,就是 cur[1]*cur[0] ->'22'。
之前把输入文件的名字固定在了程序里,每次把网上的测试文件下载下来之后都需要改名,这次把命令行参数加进来了,通过命令行执行程序的时候,把输入文件名传递进来,就很方便了。这里使用的是sys.argv。可以参考http://www.faqs.org/docs/diveintopython/kgp_commandline.html
代码如下,
#!/usr/bin/python
#encoding:UTF-8
#Filename:T9Spelling.py
import sys
import string
testCaseNum = 0
T9key = {'a':('2',1),
'b':('2',2),
'c':('2',3),
'd':('3',1),
'e':('3',2),
'f':('3',3),
'g':('4',1),
'h':('4',2),
'i':('4',3),
'j':('5',1),
'k':('5',2),
'l':('5',3),
'm':('6',1),
'n':('6',2),
'o':('6',3),
'p':('7',1),
'q':('7',2),
'r':('7',3),
's':('7',4),
't':('8',1),
'u':('8',2),
'v':('8',3),
'w':('9',1),
'x':('9',2),
'y':('9',3),
'z':('9',4),
' ':('0',1)}
inname = "input.txt"
outname = "output.txt"
if len(sys.argv)>1:
inname = sys.argv[1]
outname = inname.rstrip(".in")
outname = outname + ".out"
fin = open(inname,"r")
line = fin.readline()
if not line:
print "failed to open input file"
testCaseNum = int(line)
fout = open(outname,"w")
caseNum = 0
lines = fin.readlines()
for line in lines:
caseNum = caseNum + 1
line = line.rstrip('\n')
stat = ""
answer = "Case #%d: " %(caseNum)
for ch in line:
a = T9key[ch]
if stat == a[0]:
answer = answer + " "
stat = a[0]
answer = answer + a[1]*a[0]
answer = answer + "\n"
fout.write(answer)
fin.close()
fout.close()
如果大家有更好的方法,希望能多交流。