题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6515
解题思路:
一、解题报告里的题解:
理解了一下:p表示第i*8+j个二进制位应该属于转化后的第几个数
(s[i]&1)表示当前位的数字是1还是0
#define p (i*8+j)/6
int n=strlen(s);
for(int i=0;i<n;i++)
for(int j=0;j<8;j++,s[i]>>=1) a[p]=(a[p]<<1)+(s[i]&1);
二、我做的比较麻烦:
①输入3n个字符,每三个数字转化为四个数字输出
举个例子:(小写字母+数字表示这个数二进制第几位)
A:a8a7a6a5a4a3a2a1
B:b8b7b6b5b4b3b2b1
C:c8c7c6c5c4c3c2c1
-->转化为这样四个数
00a8a7a6a5a4a3
00a2a1b8b7b6b5
00b4b3b2b1c8c7
00c6c5c4c3c2c1
②利用二进制我们知道可以取到一个数一段正序的的:
类似这样
eg. 取a3-a8: (a<<2)%256 ---》 a3a4a5a6a7a800
再>>2 ---》 00a3a4a5a6a7a8
再搞一个函数,暴力反转。
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e+5;
int bina[7];
char str[N*3];
int fz(int a)
{
int ans=0;
for (int i=0;i<6;i++) bina[i] = (a>>i)%2;
for (int i=0;i<6;i++) ans += (bina[i]<<(5-i));
return ans;
}
void print(int a,int b,int c)
{
printf("%d %d %d %d",fz( ((a<<2)%256)>>2 ),fz( (((b<<4)%256)>>2) + (a>>6) ),fz( (b>>4) + (((c<<6)%256)>>2) ),fz( c>>2 ));
}
int main()
{
while (~scanf("%s",str)){
int len = strlen(str)/3;
for (int i=0;i<len;i++){
print(str[i*3+0],str[i*3+1],str[i*3+2]);
printf(" ");
}
}
return 0;
}