负k进制

1. k进制

(base.cpp/c/pas)

【问题描述】

众所周知,进制转换是计算机工作的基础之一。然而传统的进制,如二进制、十进制等,为表示一个负数,往往需要加前导的符号位,如何才能规避符号位呢?

负进制应运而生了。所谓负k进制,第i低位的值j可以取0~k-1k个数(大于9ABCDEF等表示),分别表示j*(-k)^(i-1),如(110)2=1*4+1*(-2)+0*1=2

你的任务即编程计算某十进制整数x,在-k进制下的表示,忽略多余的前导0

 

【输入】

包含若干行,每行两个整数xk

 

【输出】

对每组输入输出一行,一串由0~k-1构成的序列,即-k进制下x的表达。

 

【输入输出样例】

base.in

base.out

-13 2

110111

 

【数据范围】

对于30%的数据,k=20<x<100

对于另外20%的数据,k<=3|x|<100

对于100%的数据,1<k<17x在带符号长整形范围内,数据行数不超过100


考场上逆向思维打了个爆搜..骗了50

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 100;
const long long MAX = (1LL << 31);
typedef long long LL;
typedef double DB;
inline int get(){
	char c;
	while((c = getchar()) < '0' || c > '9');
	int cnt = c - '0';
	while((c = getchar()) >= '0' && c <= '9') cnt = cnt * 10 + c - '0';
	return cnt;
}
int ans[MAXN + 10],tota;
LL X,K,dept;
LL tot[MAXN + 10];
bool flag = false;
inline void dfs(LL t,int dep){
	if(dep >= dept) return;
	if(flag) return;
	for(int i = 0; i < K; i ++){
		int p = ans[dep];
		ans[dep] = i;
		if(dep & 1) t += i * tot[dep];
		else t -= i * tot[dep];
		if(t == X){
			flag = true;
			tota = dep;
			return;
		}
		dfs(t,dep + 1);
		if(flag) return;
		ans[dep] = p;
		if(dep & 1) t -= i * tot[dep];
		else t += i * tot[dep];
	}
}
int main(){
	#ifdef lwy
		freopen("1.txt","r",stdin);
	#else
		freopen("base.in","r",stdin);
		freopen("base.out","w",stdout);
	#endif
	while(scanf("%lld %lld",&X,&K) != EOF){
/*		memset(tot,0,sizeof(tot));
		memset(ans,0,sizeof(ans));
		tot[0] = 0; tot[1] = 1; tot[2] = K;
		for(int i = 3; tot[i - 3] <= abs(X); i ++){
			tot[i] = tot[i - 1] * K;
			dept = i;
		}
		flag = false; */
		for(int i = 1; i )
		for(int i = tota; i >= 1; i --){
			if(ans[i] < 10) printf("%d",ans[i]);
			if(ans[i] == 10) printf("A");
			if(ans[i] == 11) printf("B");
			if(ans[i] == 12) printf("C");
			if(ans[i] == 13) printf("D");
			if(ans[i] == 14) printf("E");
			if(ans[i] == 15) printf("F");
		}		
		printf("\n");
	}

	return 0;
}



然而仔细观察可以发现,这个-k进制和k进制是很像的。如果我们把把十进制转k进制拆开来看,相当于是每次求出当前数的最后一位,直到当前数为0。可以发现-k进制也可以这样表示,只不过在奇数位时除数为正数,偶数位时除数为负数,那这样就能轻松写出解了。

这里要注意下负数的取模

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 0;
typedef long long LL;
typedef double DB;
inline int get(){
	char c;
	while((c = getchar()) < '0' || c > '9');
	int cnt = c - '0';
	while((c = getchar()) >= '0' && c <= '9') cnt = cnt * 10 + c - '0';
	return cnt;
}
LL X,K;
int tot;
int ans[MAXN + 10];
int main(){
	#ifdef lwy
		freopen("1.txt","r",stdin);
		freopen("1o.txt","w",stdout);
	#else
		freopen("base.in","r",stdin);
		freopen("base.out","w",stdout);
	#endif
	while(scanf("%lld%lld",&X,&K) != EOF){
		tot = 0;
		memset(ans,0,sizeof(ans));
		if(X == 0){
			printf("0\n"); // 
			continue;
		}
		while(X != 0){
			ans[++tot] = (X % K + K) % K;
			X -= ans[tot];
			X /= (-K);
		}
		for(int i = tot; i >= 1; i --){
			if(ans[i] < 10){
				printf("%d",ans[i]);
			}
			else{
				printf("%c",(ans[i] - 10) + 'A');
			}
		}
		printf("\n");
	}
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值