51Nod_1925 进制转换
http://www.51nod.com/Challenge/Problem.html#!#problemId=1925
题目
有一个变进制系统从低位到高位的权值依次是 1,3,7,15,31,... 。即第i(i>=0)位的权值是 2i+1−1 。每一位数字是0,1,或者2。现在有一个十进制的数字n,想要把它转换成变进制系统下面的表示。由于有2的存在,这种转换可能会有多种可能,现在规定2只能作为最低非0位出现,这种情况下,表示就唯一了。比如44可能用15+15+7+7(2200)来表示,但是这样前面那个2就没有作为最低非0位出现,所以不符合要求,正确的转换是10120。
输入
多组测试数据。第一行有一个整数T(1<=T<=5),表示测试数据的数目。接下来T行,每行一个整数n(0<=n<=1000000000)。
输出
对于每一个n,输出它的变进制表示。
样例输入
4
1
2
3
4
样例输出
1
2
10
11
分析
枚举2出现的位置,然后从高位往低位计算该位为0还是为1,具体看程序。
C++程序
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int a[31]={0},res[31];
//计算各位的权重
int sum=1,n,t;
for(int i=1;i<=30;i++)
{
sum*=2;
a[i]=sum-1;
}
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
//寻找权值小于等于n的最高位
int k=30;
while(k>=0&&n<a[k])
k--;
if(k==0)
{
printf("0\n");
continue;
}
//枚举2的位置,i=0时表示没有2
for(int i=0;i<=k;i++)
{
memset(res,0,sizeof(res));
int temp=n;
res[i]=2;
temp-=2*a[i];
for(int j=k;j>i;j--)
if(a[j]<=temp)
{
res[j]=1;
temp-=a[j];
}
//找到答案
if(temp==0)
{
for(int j=k;j>0;j--)
printf("%d",res[j]);
printf("\n");
break;
}
}
}
return 0;
}