算法竞赛--进制转换

1.又一版A+B

输入两个不超过整型定义的非负10进制整数A和B(<=231-1),输出A+B的m (1 < m <10)进制数。

输入信息:

测试输入包含若干测试用例。每个测试用例占一行,给出m和A,B的值。当m为0时输入结束。

输出信息:

每个测试用例的输出占一行,输出A+B的m进制数。

样例输入:

1
2
3
2 4 5
8 123 456
0

样例输出:

1
2
1001
1103

hint:注意输入的两个数相加后的结果可能会超过int和long的范围。

注意:

(1)题目为非负整数,0也可以,要用do while循环。

(2)每个测试用例占一行,输出要及时换行。

(3)最最最重要,WA50%,搞了好久,在hint,a和b必须也是long long型,否则超出范围.

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<stdio.h>
int c[100];
int main()
{
long long a,b;
int m;
while(scanf("%d",&m) && m) //先输入m并判断是否等于0
{
scanf("%lld%lld",&a,&b);
long long sum=a+b;
int count=0;
do{
c[count++]=sum%m;
sum=sum/m;
}while(sum>0);
for(int i=count-1;i>=0;i--)//逆序打印输出
printf("%d",c[i]);
printf("\n");
}
return 0;
}

2.数制转换

求任意两个不同进制非负整数的转换(2进制~16进制),所给整数在long所能表达的范围之内。不同进制的表示符号为(0,1,…,9,a,b,…,f)或者(0,1,…,9,A,B,…,F)。

输入信息:

输入只有一行,包含三个整数a,n,b。a表示其后的n 是a进制整数,b表示欲将a进制整数n转换成b进制整数。a,b是十进制整数,2 =< a,b <= 16。

输出信息:

可能有多组测试数据,对于每组数据,输出包含一行,该行有一个整数为转换后的b进制数。输出时字母符号全部用大写表示,即(0,1,…,9,A,B,…,F)。

样例输入:

1
4 123 10

样例输出:

1
27

思路:将要转换的数字通过字符串输入,转换为10进制数,10进制数再进行转换,存储在字符串中,逆序输出。

注意:输入可以是大小写的a,输出则统一为大写,WA50%。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <string.h>
char a[50],b[50];
int main()
{
int n,m;
while(scanf("%d%s%d",&n,a,&m)==3)
{
int l=strlen(a),temp=1;
long long sum=0;
for(int i=l-1;i>=0;i--) //从低位开始循环
{
if(a[i]>='A'&&a[i]<='F')//若该字符为A-F,转换为10-15的数字
sum+=(a[i]-'7')*temp;
if(a[i]>='a'&&a[i]<='F')//若该字符为a-f,转换为10-15的数字
sum+=(a[i]-'A'-22)*temp;
if(a[i]>='0'&&a[i]<='9')//若该字符为0-0,转换为0-9的数字
sum+=(a[i]-'0')*temp;//该数字与对应的权重相乘累加求和
temp*=n;//计算每位数上的权重
}
int count=0;
do{
if(sum%m>=10) //如果取余的数字大于10,转换为A-F的字符
b[count++]=(sum%m)+'7';
else //否则转换为0-9字符
b[count++]=(sum%m)+'0';
sum=sum/m;
}while(sum>0);
for(int i=count-1;i>=0;i--)//逆序打印输出
printf("%c",b[i]);
printf("\n");
}
return 0;
}

3.进制转换

将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。

输入信息:

多组数据,每行为一个长度不超过30位的十进制非负整数。(注意是10进制数字的个数可能有30个,而非30bits的整数)

输出信息:

每行输出对应的二进制数。

样例输入:

1
2
3
985
211
1126

样例输出:

1
2
3
1111011001
11010011
10001100110

注意:

(1)多组输入输出
(2)起初想用long long 型存储,题目要求30位,long long最多20位,用字符数组接收
(3)保存二进制数的数组,要大一些,我开辟了50的空间,一直报RE50%的错误。

思路:用字符数组接收,将每个字符转换为整型,从最后一个数字开始逐步除二取余,存储在新数组中,再将整个数除二存储。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <string.h>
int main()
{
char a[35];
while(scanf("%s",a)==1)
{
int len=strlen(a);
int b[35]={0};
for(int i=0;i<len;i++)//从高位开始,将每个字符转换为对应的数字
b[i]=a[i]-'0';
int k=0,num=0;
int z[100]={0}; //存储进制数的数组,空间要开辟的足够大
while(k<len)
{
int q=0;
z[num++]=(b[len-1])%2;//从最后一位开始逐步取余
for(int j=k;j<len;j++)//将原数除以二并存储
{
int temp=b[j];
b[j]=(b[j]+q)/2;//从最高位开始,如果是偶数,可以除尽,q=0;如果是奇数,会余1给下一位,下一位加10之后再进行除法运算。
if(temp%2)
q=10;
else
q=0;
}
if(b[k]==0)
k++;
}
for(int i=num-1;i>=0;i--)
printf("%d",z[i]);
printf("\n");
}
return 0;
}

4.日期累加

设计一个程序能计算一个日期加上若干天后是什么日期。

输入信息:

输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数。

输出信息:

输出m行,每行按yyyy-mm-dd的个数输出。

样例输入:

1
2
1
2008 2 3 100

样例输出:

1
2008-05-13

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<stdio.h>
int month[13][2]={{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};
bool Isleap(int year)
{
return ((year%4==0&&year%10!=0)||(year%400==0));
}
int main()
{
int n,y,m,d,count;
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d%d",&y,&m,&d,&count);
while(count--) //该题为3的变式,累加count次即可
{
d++;
if(d==month[m][Isleap(y)]+1)
{
m++;
d=1;
}
if(m==13)
{
y++;
m=1;
}
}
printf("%04d-%02d-%02d\n",y,m,d);
}
return 0;
}

5.日期计算

已知2011年11月11日是星期五,问YYYY年MM月DD日是星期几?注意考虑闰年的情况。尤其是逢百年不闰,逢400年闰的情况。

输入信息:

输入只有一行
YYYY MM DD

输出信息:

输出只有一行
W

样例输入:

1
2011 11 11

样例输出:

1
5

代码如下:

图

小礼物走一个哟
0%