南邮 OJ 1504 进制转换

本文探讨了进制转换的概念及应用,详细介绍了Openxxx发明的通项公式,并通过实例展示了如何将不同进制下的数转换为目标进制下的数。算法实现部分提供了具体的步骤和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进制转换

时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65535 KByte
总提交 : 112            测试通过 : 29 

比赛描述

Openxxx发现,我们所熟知十进制、二进制、十六进制都是一类很特殊的进制,其实进制有着更一般的情况。Openxxx发明了一种进制表示的通项公式:K~(a1,a2,……,ak-1,ak), 其中K代表进制的循环节长度,向量 (a1,a2,……,ak-1,ak) 是对循环节的描述。比如我们所熟知的十进制,二进制,十六进制可依次表示为 1~(10),1~(2)和1~(16),他们都属于循环节长度为1的进制。如果长度大于1会怎么样?不妨让我们观察一下进制2~(10,2)从0开始计数的情况:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,100?

为什么不是20呢?因为在此进制下第2位的位权是2,所以第2位上应该逢2进1。第3位呢?我们可以循环利用前面的位权,第3位就和第1位一样逢10进1,第4位就和第2位一样逢2进1,如此循环下去……

现在的问题是:给你两种不同的进制,请将原进制下的数转换成目标进制下的数。为了方便数的表达,我们用大写字母’A’~’Z’来代替10~35。



输入

多组测试数据,每组数据第1行输入两个正整数K1、K2,分别描述原进制和目标进制的循环节长度;第2行输入一串长度不超过30的字串(仅由 ’0’~’9’ 和’A’~’Z’ 构成),即原进制下的数。数据保证是合法的;第3行输入K1个正整数a1 ,…,ak1,第4行输入K2个正整数b1,…,bk2,分别描述原进制和目标进制的循环节。(1≤K1, K2≤10;2≤所有a, b≤36;0≤待转换的数≤2^30) 输入直至文件结尾。

输出

每组数据输出仅一行:转换后的目标数。

样例输入

1 1
8
10
2
2 2
ABC
16 15
14 13

样例输出

1000
102C

提示

 

题目来源

openxxx





/* Wrong Answer at Test 1
#include<iostream>
#define N 32
int ow[N];				//original weight原操作数对应的权重
int on[N];				//original number原操作数
int tw[N];				//target weight目的操作数对位的权重
int tn[N];				//target number目的操作数
char temp[N];			//存放接收到的数据
int tempW[N];			//每一位的权重

//字符转化为数字,c[0]表示最高位,n[0]表示个位
void charToNum(char *c,int *n,int len){
	int i;
	for(i=0;i<len;i++){
		if(c[i]>='0' && c[i]<='9'){
			n[len-1-i] = c[i]-'0';
		}else{
			n[len-1-i] = c[i]-'A'+10;
		}
	}
}

void numToChar(int *n,char *c,int len){
	int i;
	for(i=0;i<len;i++){
		if(n[i]<10){
			c[len-1-i] = n[i]+'0';
		}else{
			c[len-1-i] = n[i]-10+'A';
		}
	}
	c[len] = 0;
}

int main(){
//	freopen("test.txt","r",stdin);
	int K1,K2,i,oLen,tLen,r;
	while(scanf("%d%d",&K1,&K2)==2){
		scanf("%s",temp);
		oLen = strlen(temp);	//原操作数的长度
		charToNum(temp,on,oLen);
		for(i=0;i<K1;i++){
			scanf("%d",&tempW[i]);
		}
		ow[0] = 1;
		for(i=1;i<N;i++){		//会溢出,先不管
			ow[i] = ow[i-1]*tempW[(i-1)%K1];
		}
//		for(i=0;i<N;i++){
//			printf("%d\n",ow[i]);
//		}
		for(i=0;i<K2;i++){
			scanf("%d",&tempW[i]);
		}
		tw[0] = 1;
		for(i=1;i<N;i++){
			tw[i] = tw[i-1]*tempW[(i-1)%K2];
		}
//		for(i=0;i<N;i++){
//			printf("%d\n",tw[i]);
//		}
		r = 0;
		for(i=0;i<oLen;i++){
			r += on[i]*ow[i];
		}
		if(r==0){
			printf("0\n");
		}
		for(tLen=0;r>=tw[tLen];tLen++);
		tLen;
		for(i=tLen-1;i>=0;i--){
			tn[i] = r/tw[i];
			r %= tw[i];
		}
		numToChar(tn,temp,tLen);
		printf("%s\n",temp);
	}
}
*/

/* Presentation Error at Test 1
#include<iostream>
#define N 40
__int64 ow[N];				//original weight原操作数对应的权重
__int64 on[N];				//original number原操作数
__int64 tw[N];				//target weight目的操作数对位的权重
__int64 tn[N];				//target number目的操作数
char temp[N];				//存放接收到的数据
__int64 tempW[N];			//每一位的权重

//字符转化为数字,c[0]表示最高位,n[0]表示个位
void charToNum(char *c,__int64 *n,__int64 len){
	__int64 i;
	for(i=0;i<len;i++){
		if(c[i]>='0' && c[i]<='9'){
			n[len-1-i] = c[i]-'0';
		}else{
			n[len-1-i] = c[i]-'A'+10;
		}
	}
}

void numToChar(__int64 *n,char *c,__int64 len){
	__int64 i;
	for(i=0;i<len;i++){
		if(n[i]<10){
			c[len-1-i] = n[i]+'0';
		}else{
			c[len-1-i] = n[i]-10+'A';
		}
	}
	c[len] = 0;
}

int main(){
//	freopen("test.txt","r",stdin);
	__int64 K1,K2,i,oLen,tLen,r;
	while(scanf("%I64d%I64d",&K1,&K2)==2){
		scanf("%s",temp);
		oLen = strlen(temp);	//原操作数的长度
		charToNum(temp,on,oLen);
		for(i=0;i<K1;i++){
			scanf("%I64d",&tempW[i]);
		}
		ow[0] = 1;
		for(i=1;i<N;i++){		//会溢出,先不管
			ow[i] = ow[i-1]*tempW[(i-1)%K1];
		}
//		for(i=0;i<N;i++){
//			printf("%d\n",ow[i]);
//		}
		for(i=0;i<K2;i++){
			scanf("%I64d",&tempW[i]);
		}
		tw[0] = 1;
		for(i=1;i<N;i++){
			tw[i] = tw[i-1]*tempW[(i-1)%K2];
		}
//		for(i=0;i<N;i++){
//			printf("%d\n",tw[i]);
//		}
		r = 0;
		for(i=0;i<oLen;i++){
			r += on[i]*ow[i];
		}
		if(r==0){
			printf("0\n");
		}
		for(tLen=0;r>=tw[tLen];tLen++);
		tLen;
		for(i=tLen-1;i>=0;i--){
			tn[i] = r/tw[i];
			r %= tw[i];
		}
		numToChar(tn,temp,tLen);
		printf("%s\n",temp);
	}
}
*/


#include<iostream>
#define N 40
__int64 ow[N];				//original weight原操作数对应的权重
__int64 on[N];				//original number原操作数
__int64 tw[N];				//target weight目的操作数对位的权重
__int64 tn[N];				//target number目的操作数
char temp[N];				//存放接收到的数据
__int64 tempW[N];			//每一位的权重

//字符转化为数字,c[0]表示最高位,n[0]表示个位
void charToNum(char *c,__int64 *n,__int64 len){
	__int64 i;
	for(i=0;i<len;i++){
		if(c[i]>='0' && c[i]<='9'){
			n[len-1-i] = c[i]-'0';
		}else{
			n[len-1-i] = c[i]-'A'+10;
		}
	}
}

void numToChar(__int64 *n,char *c,__int64 len){
	__int64 i;
	for(i=0;i<len;i++){
		if(n[i]<10){
			c[len-1-i] = n[i]+'0';
		}else{
			c[len-1-i] = n[i]-10+'A';
		}
	}
	c[len] = 0;
}

int main(){
//	freopen("test.txt","r",stdin);
	__int64 K1,K2,i,oLen,tLen,r;
	while(scanf("%I64d%I64d",&K1,&K2)==2){
		scanf("%s",temp);
		oLen = strlen(temp);	//原操作数的长度
		charToNum(temp,on,oLen);
		for(i=0;i<K1;i++){
			scanf("%I64d",&tempW[i]);
		}
		ow[0] = 1;
		for(i=1;i<N;i++){		//会溢出,先不管
			ow[i] = ow[i-1]*tempW[(i-1)%K1];
		}
//		for(i=0;i<N;i++){
//			printf("%d\n",ow[i]);
//		}
		for(i=0;i<K2;i++){
			scanf("%I64d",&tempW[i]);
		}
		tw[0] = 1;
		for(i=1;i<N;i++){
			tw[i] = tw[i-1]*tempW[(i-1)%K2];
		}
//		for(i=0;i<N;i++){
//			printf("%d\n",tw[i]);
//		}
		r = 0;
		for(i=0;i<oLen;i++){
			r += on[i]*ow[i];
		}
		if(r==0){
			printf("0\n");
			continue;				//PE1
		}
		for(tLen=0;r>=tw[tLen];tLen++);
		tLen;
		for(i=tLen-1;i>=0;i--){
			tn[i] = r/tw[i];
			r %= tw[i];
		}
		numToChar(tn,temp,tLen);
		printf("%s\n",temp);
	}
}



内容概要:本文探讨了在MATLAB/SimuLink环境中进行三相STATCOM(静态同步补偿器)无功补偿的技术方法及其仿真过程。首先介绍了STATCOM作为无功功率补偿装置的工作原理,即通过调节交流电压的幅值和相位来实现对无功功率的有效管理。接着详细描述了在MATLAB/SimuLink平台下构建三相STATCOM仿真模型的具体步骤,包括创建新模型、添加电源和负载、搭建主电路、加入控制模块以及完成整个电路的连接。然后阐述了如何通过对STATCOM输出电压和电流的精确调控达到无功补偿的目的,并展示了具体的仿真结果分析方法,如读取仿真数据、提取关键参数、绘制无功功率变化曲线等。最后指出,这种技术可以显著提升电力系统的稳定性与电能质量,展望了STATCOM在未来的发展潜力。 适合人群:电气工程专业学生、从事电力系统相关工作的技术人员、希望深入了解无功补偿技术的研究人员。 使用场景及目标:适用于想要掌握MATLAB/SimuLink软件操作技能的人群,特别是那些专注于电力电子领域的从业者;旨在帮助他们学会建立复杂的电力系统仿真模型,以便更好地理解STATCOM的工作机制,进而优化实际项目中的无功补偿方案。 其他说明:文中提供的实例代码可以帮助读者直观地了解如何从零开始构建一个完整的三相STATCOM仿真环境,并通过图形化的方式展示无功补偿的效果,便于进一步的学习与研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值