Problem F: ARM立即数寻址
Time Limit: 4 Sec Memory Limit: 128 MB
Submit: 53 Solved: 12
Description
在ARM处理器立即数寻址方式中,立即数是由一个8位的无符号常数(大于等于0,小于等于0xff),先扩展为32位,然后循环右移偶数位得到。所以类似0x101,0x102,0xFF1,0xFF04,0x8000007F等都是无效的立即数,而像0xFF,0x3FC,0xC000003F,0x104,0xFF0,0xFF00,0xf000000f等都是有效的立即数。
现在给你一个32位的正整数,请你判断这个数是否是有效的立即数。
(0x12345678循环右移4位变为0x81234567。)
Input
一个正整数T (T<= 1000000),表示有T组测试数据
每一组测试数据包含一个32位的十六进制数n (0<= n <= 0xffffffff)
Output
共T行。对于每个n,输出占一行,如果n是有效的立即数输出"YES",否则输出"NO"。
Sample Input
30xff0xFF0xF0F
Sample Output
YESYESNO
HINT
比赛时原题有错误,“大于0”应为“大于等于0”。
刚开始的做法让我做了好久.......
题意:给一个16进制数,如果这个数的32位形式按往左循环偶数位可以变成一个8位二进制数就输出YES,否则输出NO
例如:0x3FC可转化为0000 0000 0000 0000 0000 0011 1111 1100 再往左循环30位偶数位变为0000 0000 0000 0000 0000 0000 1111 1111,符合条件!!输出YES!
思路:先转化为32位,然后往左循环偶数位再看他是不是一个8位二进制数
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char a[12]; int b[80]; void writeb(int n, int a) { for(int i=4*n; i>4*(n-1); i--) { b[i] = a%2; a/=2; } } int fun(char ch) { if(ch>='0' && ch<='9') return (int)ch; else if(ch>='a' && ch<='f') return (int)ch-87; else if(ch>='A' && ch<='F') return (int)ch-55; } int judge(int i, int j) { while(!b[i])i++; return j-i+1; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%s", a); memset(b, 0, sizeof(b)); int num=8; for(int i=strlen(a)-1; a[i]!='x'; i--) { writeb(num, fun(a[i])); num--; } int min = judge(1,32); for(int i=2; i<=30; i+=2) { int j; for(j=1; j<=i; j++) { b[32+j] = b[j]; } if(judge(1+i, 32+i)<min)min=judge(1+i, 32+i); } if(min<=8)printf("YES\n"); else printf("NO\n"); } return 0; }
之前做了1个多小时的逗比做法,今天我怎么了......
逗比了的代码(做着做着我整个人都不好了,贴下当个教训...):
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; char a[12], b[45]; int fun1(char ch) { if(ch>'0' && ch<='1') return 1; else if(ch>='2' && ch<='3') return 2; else if(ch>='4' && ch<='7') return 3; else return 4; } int fun2(char ch) { int num, de=4; if(ch>'0' && ch<='9') num = ch-'0'; else if(ch>='a' && ch<='f') num = ch-'0'-87; else if(ch>='A' && ch<='F') num = ch-'0'-55; while(num) { if(num%2==1) return de; else { num/=2; de--; } } } int judge1(char a[]) { int count = 0; for(int i=2; a[i]!='\0'; i++) { if(a[i]!='0')count++; } return count; } int judge2(char a[]) { int len = strlen(a); for(int i=2; i<len-1; i++) { if(a[i]!='0'&&a[i+1]!='0')return 1; } if(a[2]!='0' && a[len-1]!='0' && len==10)return 1; for(int i=2; i<len-2; i++) { if(fun1(a[i]) + fun2(a[i+2]) <=4)return 1; } if(len==10&&a[2]!='0' && a[len-2]!='0'&&fun1(a[2])+fun2(a[len-2])<=4)return 1; if(len==10&&a[3]!='0'&&a[len-1]!='0'&&fun1(a[len-1])+fun2(a[3])<=4)return 1; return 0; } int judge3(char a[]) { int len = strlen(a); for(int i=2; i<len-2; i++) { if(a[i]!='0'&&a[i+1]!='0'&&a[i+2]!='0')return i; } if(a[2]!='0'&&a[3]!='0'&&a[len-1]!='0'&&len==10)return -1; if(a[2]!='0'&&a[len-2]!='0'&&a[len-1]!='0'&&len==10)return -2; return 0; } int judge4(char a[], int i) { int len = strlen(a); if(i>0 && (fun1(a[i])+fun2(a[i+2])<=4))return 1; else if(i==-1 && (fun1(a[len-1])+fun2(a[3])<=4)) return 1; else if(i==-2 && (fun1(a[len-2])+fun2(a[2])<=4)) return 1; else return 0; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%s", a); if(judge1(a)>3) { printf("NO\n"); continue; } if(judge1(a)<=1) { printf("YES\n"); continue; } if(judge1(a)==2) { if(judge2(a)) { printf("YES\n"); continue; } else { printf("NO\n"); continue; } } int xia; if(judge1(a) == 3) { if(xia = judge3(a)) { if(judge4(a, xia)){ printf("YES\n"); continue;} else { printf("NO\n"); continue;} } else { printf("NO\n"); continue; } } } return 0; }