[ZOJ 3883] Scan Code 劳民伤财+劳神+并不科学的一个 模拟题
2015-07-27 20:13
309 查看
先贴聊天记录一部分:
<zimpha#************> 2015-07-26 18:51:25
C题是我那个大四的final队友出的题....描述不清...坑人无数
<zimpha#************> 18:54:43
现在内部题库里面已经没啥可用的题了..于是就挂出了这些恶心题
……说恶心,也没办法,硬着头皮做。
反正任务很简单,就是,翻译扫描码并做相应操作。
(扫描码的工作机制的话,就是每个按键有2个码,一个通码Make Code一个断码Break Code,按下的时候发一个通码,松开的时候发一个断码,具体机制可以参见《自己动手写操作系统》一书,自己用汇编+C语言写一个能处理键盘输入的,DOS味十足的底层程序,当然这不是这里的重点)
其他按键都还好了,只有4个特殊按键需要照顾:左右Shift、Caps Lock、Backspace。
然后他们怎么样的工作机制?!题目一句话都没说!!!!!!
题目居然忘了说明白这个看起来小但完全能影响结果的事情了!!!!!!
更糟糕的是,这些按键的组合行为在不同系统,不同编辑器下行为完全不同!
比如:
大写锁关闭,按住CapsLock,然后打英文字母,Win下打出来的是大写字母,Mac下打出来的是小写字母!
按住Shift,然后按Tab,Windows的记事本下还是会输出一个制表符( ' \t ' ),但是在Linux的gedit、Win的代码编辑器下,是撤销了缩进(删除一个制表符)!
你按下Backspace的时候要我输出\b(ASCII 8,表Backspace)还是删去一个字符?
搞不清楚的细节问题太多了,想发 Clarification 问一下却不行,无力吐槽……
好吧,我们就按照Win下的行为写:
按下CapsLock时,大写锁状态翻转,在按下期间CapsLock的状态不变(不管发了多少Make Code),直到松开后再次按下
2个Shift互不干扰,CapsLock关闭的情况下,只要按下任何一个Shift,小写边大写,有2个字符的按键则打上面那个字符。两个Shift都按下的情况同理
CapsLock打开的情况下,按下任何一个Shift,按字母按键,输出小写字母,有2个字符的按键还是打上面那个字符。
按住Shift和不按住Shift的时候按Tab,行为一致,输出一个 ' \t '(制表符)
按下Backspace,收到一个Make Code就删除一个字符。
具体到实现的时候,主要就是,别偷懒,CapsLock除了需要标记是否打开,还要记得标记现在是否按下,按下了以后再发来Make Code就不要翻转CapsLock的状态了。
还有左右Shift,这两个Shift用2个独立变量标记是否按下。
还有请千万别没字符了还删,删除到负下标去了。
——诶呀,比赛没时间了,懒得打表怎么办?
——百度搜搜看啊,这种扫描码不可能一个个都造过去的
听从队友的建议,于是搜到了下面这两个
http://www.computer-engineering.org/ps2keyboard/scancodes2.html
http://www.computer-engineering.org/ps2keyboard/scancodes3.html
好像是现成的扫描码表格啊!
粘贴到Excel里,简单处理一下,搞到Notepad++里,然后整成代码的一部分,贴进代码里,最后补上那些特别的按键的行为控制,然后提交,WA……
……改了半天还是WA……
……赛后补题的时候发现,好像有的按键不对啊,题目里给的Make Code,和网上找的PS/2键盘实际的扫描码不一样啊!
于是折腾了1个小时,一个个对过去,终于改完,然后过了……
然后用Beyond Compare比对了一下前后的代码,发现出题人改了11个地方的MakeCode和相应的BreakCode……
论出题人的心态与RP。
最后贴一下代码
<zimpha#************> 2015-07-26 18:51:25
C题是我那个大四的final队友出的题....描述不清...坑人无数
<zimpha#************> 18:54:43
现在内部题库里面已经没啥可用的题了..于是就挂出了这些恶心题
……说恶心,也没办法,硬着头皮做。
反正任务很简单,就是,翻译扫描码并做相应操作。
(扫描码的工作机制的话,就是每个按键有2个码,一个通码Make Code一个断码Break Code,按下的时候发一个通码,松开的时候发一个断码,具体机制可以参见《自己动手写操作系统》一书,自己用汇编+C语言写一个能处理键盘输入的,DOS味十足的底层程序,当然这不是这里的重点)
其他按键都还好了,只有4个特殊按键需要照顾:左右Shift、Caps Lock、Backspace。
然后他们怎么样的工作机制?!题目一句话都没说!!!!!!
题目居然忘了说明白这个看起来小但完全能影响结果的事情了!!!!!!
更糟糕的是,这些按键的组合行为在不同系统,不同编辑器下行为完全不同!
比如:
大写锁关闭,按住CapsLock,然后打英文字母,Win下打出来的是大写字母,Mac下打出来的是小写字母!
按住Shift,然后按Tab,Windows的记事本下还是会输出一个制表符( ' \t ' ),但是在Linux的gedit、Win的代码编辑器下,是撤销了缩进(删除一个制表符)!
你按下Backspace的时候要我输出\b(ASCII 8,表Backspace)还是删去一个字符?
搞不清楚的细节问题太多了,想发 Clarification 问一下却不行,无力吐槽……
好吧,我们就按照Win下的行为写:
按下CapsLock时,大写锁状态翻转,在按下期间CapsLock的状态不变(不管发了多少Make Code),直到松开后再次按下
2个Shift互不干扰,CapsLock关闭的情况下,只要按下任何一个Shift,小写边大写,有2个字符的按键则打上面那个字符。两个Shift都按下的情况同理
CapsLock打开的情况下,按下任何一个Shift,按字母按键,输出小写字母,有2个字符的按键还是打上面那个字符。
按住Shift和不按住Shift的时候按Tab,行为一致,输出一个 ' \t '(制表符)
按下Backspace,收到一个Make Code就删除一个字符。
具体到实现的时候,主要就是,别偷懒,CapsLock除了需要标记是否打开,还要记得标记现在是否按下,按下了以后再发来Make Code就不要翻转CapsLock的状态了。
还有左右Shift,这两个Shift用2个独立变量标记是否按下。
还有请千万别没字符了还删,删除到负下标去了。
——诶呀,比赛没时间了,懒得打表怎么办?
——百度搜搜看啊,这种扫描码不可能一个个都造过去的
听从队友的建议,于是搜到了下面这两个
http://www.computer-engineering.org/ps2keyboard/scancodes2.html
http://www.computer-engineering.org/ps2keyboard/scancodes3.html
好像是现成的扫描码表格啊!
粘贴到Excel里,简单处理一下,搞到Notepad++里,然后整成代码的一部分,贴进代码里,最后补上那些特别的按键的行为控制,然后提交,WA……
……改了半天还是WA……
……赛后补题的时候发现,好像有的按键不对啊,题目里给的Make Code,和网上找的PS/2键盘实际的扫描码不一样啊!
于是折腾了1个小时,一个个对过去,终于改完,然后过了……
然后用Beyond Compare比对了一下前后的代码,发现出题人改了11个地方的MakeCode和相应的BreakCode……
论出题人的心态与RP。
最后贴一下代码
#include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <math.h> #include <algorithm> #include <map> using namespace std; typedef long long ll; map<int,char> smalldict,largedict; char ans[5000005]; int ap; char input[5000005]; void addChar(char x){ ans[ap++]=x; ans[ap]=0; } bool caps; bool Rshift; bool Lshift; bool capsDown; int special_Control(int x){ if(x==0x66){//backspace return 5; }else if(x==0x21){ return ' '; }else if(x==0x0D){ return '\t'; }else if(x==0x58){//caps 2 return 2; }else if(x==0x59){//Rshift 3 return 3; }else if(x==0x12){//LShift 4 return 4; }else if(x==0x5A){ return '\n'; }else return 0; } int char2int(char a,char b){ int x1,x2; if(isdigit(a)) x1=a-'0'; else x1=a-'A'+10; if(isdigit(b)) x2=b-'0'; else x2=b-'A'+10; return x1*16+x2; } int main(){ smalldict[0x1C]='a'; smalldict[0x32]='b'; smalldict[0x29]='c'; smalldict[0x25]='d'; smalldict[0x24]='e'; smalldict[0x2B]='f'; smalldict[0x33]='g'; smalldict[0x34]='h'; smalldict[0x43]='i'; smalldict[0x3B]='j'; smalldict[0x42]='k'; smalldict[0x4B]='l'; smalldict[0x3A]='m'; smalldict[0x31]='n'; smalldict[0x44]='o'; smalldict[0x4D]='p'; smalldict[0x15]='q'; smalldict[0x2C]='r'; smalldict[0x1B]='s'; smalldict[0x2D]='t'; smalldict[0x3C]='u'; smalldict[0x2A]='v'; smalldict[0x1D]='w'; smalldict[0x45]='x'; smalldict[0x35]='y'; smalldict[0x1A]='z'; smalldict[0x22]='0'; smalldict[0x16]='1'; smalldict[0x1E]='2'; smalldict[0x26]='3'; smalldict[0x23]='4'; smalldict[0x2E]='5'; smalldict[0x36]='6'; smalldict[0x3D]='7'; smalldict[0x3E]='8'; smalldict[0x46]='9'; smalldict[0x0E]='`'; smalldict[0x4E]='-'; smalldict[0x55]='='; smalldict[0x5D]='\\'; smalldict[0x54]='['; smalldict[0x5B]=']'; smalldict[0x4C]=';'; smalldict[0x52]='\''; smalldict[0x41]=','; smalldict[0x49]='.'; smalldict[0x4A]='/'; largedict[0x1C]='A'; largedict[0x32]='B'; largedict[0x29]='C'; largedict[0x25]='D'; largedict[0x24]='E'; largedict[0x2B]='F'; largedict[0x33]='G'; largedict[0x34]='H'; largedict[0x43]='I'; largedict[0x3B]='J'; largedict[0x42]='K'; largedict[0x4B]='L'; largedict[0x3A]='M'; largedict[0x31]='N'; largedict[0x44]='O'; largedict[0x4D]='P'; largedict[0x15]='Q'; largedict[0x2C]='R'; largedict[0x1B]='S'; largedict[0x2D]='T'; largedict[0x3C]='U'; largedict[0x2A]='V'; largedict[0x1D]='W'; largedict[0x45]='X'; largedict[0x35]='Y'; largedict[0x1A]='Z'; largedict[0x22]=')'; largedict[0x16]='!'; largedict[0x1E]='@'; largedict[0x26]='#'; largedict[0x23]='$'; largedict[0x2E]='%'; largedict[0x36]='^'; largedict[0x3D]='&'; largedict[0x3E]='*'; largedict[0x46]='('; largedict[0x0E]='~'; largedict[0x4E]='_'; largedict[0x55]='+'; largedict[0x5D]='|'; largedict[0x54]='{'; largedict[0x5B]='}'; largedict[0x4C]=':'; largedict[0x52]='"'; largedict[0x41]='<'; largedict[0x49]='>'; largedict[0x4A]='?'; while(~scanf("%s",input)){ int len=strlen(input); Lshift=Rshift=caps=capsDown=false; ap=0;ans[0]=0; for(int i=0;i<len;i++) input[i]=toupper(input[i]); for(int i=0;i<len;i+=2){ int code=char2int(input[i],input[i+1]); if(code==0xF0){ int code2=char2int(input[i+2],input[i+3]); code2=special_Control(code2); if(code2==3) Rshift=false; else if(code2==4) Lshift=false; else if(code2==2) capsDown=false; i+=2; }else{ int spid=special_Control(code); if(spid==3) Rshift=true; else if(spid==4) Lshift=true; else if(spid==2){ if(!capsDown){ caps=!caps; capsDown=true; } } else if(spid==5){ if(ap) ap--; ans[ap]=0; }else if(spid){ addChar(spid); }else{ char c=smalldict[code]; if(isalpha(c)){ if(caps^(Lshift||Rshift)) c=largedict[code]; }else{ if(Lshift||Rshift) c=largedict[code]; } if(c)addChar(c); } } } puts(ans); } return 0; }
相关文章推荐
- hdu 4000 Fruit Ninja(树状数组)
- hdu 1051 Wooden Sticks
- hust 1010 The Minimum Length
- UVA156-Ananagrams
- ROS中创建工作空间
- 4.4、Libgdx用法查询执行环境相关性
- UICollectionViewFlowLayout and UICollectionView
- hdu 4000 Fruit Ninja(树状数组)
- spring mvc中的@PathVariable
- 利用ffmpeg将RTSP传输的h264原始码流保存到文件中
- 课程笔记 16:数据结构(清华) 图-邻接矩阵
- mina简单编解码器示例
- Linux下C语言执行MySQL语句 http://www.2cto.com/database/201312/268374.html
- 使用TCP协议的NAT穿透技术 (转)
- uvaLive5713 次小生成树
- c++对象模型
- 关于mysql数据库数据恢复-日志恢复
- iOS UI篇 学习笔记 UIButton,UIImageView
- 2008 数值统计
- vld