无意中看到这个比赛的,刚好也有空,就报了名。参加了初赛和决赛,貌似比想象中的要简单,不过我用c++写的,估计违法比赛规则了~
初赛:http://acm.pku.edu.cn/JudgeOnline/showcontest?contest_id=1345
1.位操作, 很简单。不过我写了3个等式,最终应该能表示成一个
int r, x, y; r = r &~(0x1<<x) r = r | (0x2<<(y-1)) r = r &~(0x1<<(y-2))
2.破译密码,就不说了
3.小孩报数,这个简单模拟,约瑟夫环的例子。
4.时间日期格式转换,这个用是scanf能很方便的读入数据
5.字母旋转游戏,这个也是模拟,先定义一个二维数组附上一个非法值,在模拟过程中走到数组的和法值就可以转换了 :)
决赛:http://acm.pku.edu.cn/JudgeOnline/showcontest?contest_id=1346
1.根据关键词进行字符串拷贝,这个也比较简单,用c++的string会比c方便一些,acm嘛,呵呵
2.模拟Modbus协议 ,这道题我觉得挺有趣的。模拟发帧,收帧还有计算CRC checksum。以前没有写过这样的程序,还是花了比较长的时间,中间同学又来看我,不过终于在比赛结束前7分钟通过。不过还是用来c++的string~。
除了IEEE转换为flat会有些问题,其他都是程序问题了。
ps:方法二来自校友剑仙魔
ps2:反过来就是float转换为ieee
方法1:float f = *((float*)&(ieee)) 方法2:float f; int ieee=0x420b999a; memcpy(&f,&ieee,4);
结果:悲剧了,今天去顶嵌的网站去看了下,只能使用GCC的编译器,所以今天早上又稍微改了下,发展只有2个地方使用了string,而且直接用char*也是ok的,所以又提交下,ok。不过貌似时间上比别人多,先贴下代码:
#include <stdio.h> #include <string.h> typedef unsigned int uint; typedef unsigned char byte; #define is_last_1(x) ((x)&1) #define shift_right_1(x) / do {/ (x)>>=1; / (x)&=0x7FFFFFF;/ }while(0); int char_to_num(char c) { if (c>='0' && c<='9') return (c-'0'); else return (c-'A'+10); } int str_to_bytes(char* str, byte *msg) { uint i, j; uint len = strlen(str); for (i=0, j=0; i<len; i+=2) msg[j++] = char_to_num(str[i])*16 + char_to_num(str[i+1]); return j; } uint cal_checksum(byte *msg, int num) { int i = 0; int j = 0; uint flag; uint crc = 0xFFFF; for (i=0; i<num; ++i) { crc ^= msg[i]; for (j=0; j<8; ++j) { flag = is_last_1(crc); shift_right_1(crc); if (flag) crc ^= 0xA001; } } crc = ((crc>>8)&0xFF) | ((crc<<8)&0xFF00); return crc; } int main() { int size; int i; uint a[4]; uint check_sum; uint ieee; byte flag; uint o_checksum; byte msg[1000]; while (scanf("%d,%d,%d,%d", &a[0], &a[1], &a[2], &a[3]) != EOF) { //send sprintf((char*)msg, "%02X%02X%04X%04X", a[0], a[1], a[2], a[3]); size = str_to_bytes((char*)msg, msg); check_sum = cal_checksum(msg, size); sprintf((char*)msg, "%02X%02X%04X%04X%04X", a[0], a[1], a[2], a[3], check_sum); printf("%s/n", msg); //receive scanf("%s", (char*)msg); size = str_to_bytes((char*)msg, msg); check_sum = cal_checksum(msg, size-2); o_checksum = ((uint)(msg[size-2]<<8) | msg[size-1]) & 0xFFFF; if (check_sum != o_checksum) { printf("CRC_ERROR/n"); continue; } flag = 0; for (i=3; i<msg[2]; i+=4) { ieee = (uint)msg[i]<<24 | msg[i+1]<<16 | msg[i+2]<<8 | msg[i+3]; if (!flag) { printf("%.1f", *((float*)&(ieee))); flag = 1; } else printf(",%.1f", *((float*)&(ieee))); } printf("/n"); } return 0; }