首页 > 代码库 > ZZUOJ-1194-ARM立即数寻址 (郑州大学第七届ACM大学生程序设计竞赛正式赛F题)

ZZUOJ-1194-ARM立即数寻址 (郑州大学第七届ACM大学生程序设计竞赛正式赛F题)

Problem F: ARM立即数寻址

Time Limit: 4 Sec  Memory Limit: 128 MB
Submit: 53  Solved: 12
[Submit][Status][Web Board]

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;
} 



ZZUOJ-1194-ARM立即数寻址 (郑州大学第七届ACM大学生程序设计竞赛正式赛F题)