您的位置:首页 > 其它

[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。

最后贴一下代码

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: