1. 负k进制
(base.cpp/c/pas)
【问题描述】
众所周知,进制转换是计算机工作的基础之一。然而传统的进制,如二进制、十进制等,为表示一个负数,往往需要加前导的符号位,如何才能规避符号位呢?
负进制应运而生了。所谓负k进制,第i低位的值j可以取0~k-1这k个数(大于9用ABCDEF等表示),分别表示j*(-k)^(i-1),如(110)2=1*4+1*(-2)+0*1=2。
你的任务即编程计算某十进制整数x,在-k进制下的表示,忽略多余的前导0。
【输入】
包含若干行,每行两个整数x、k。
【输出】
对每组输入输出一行,一串由0~k-1构成的序列,即-k进制下x的表达。
【输入输出样例】
base.in |
base.out |
-13 2 |
110111 |
【数据范围】
对于30%的数据,k=2,0
对于另外20%的数据,k<=3,|x|<100;
对于100%的数据,1
考场上逆向思维打了个爆搜..骗了50
#include
#include
#include
#include
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
#include
#include
#include
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;
}