杭电OJ第11页2030~2034算法题(C语言)

目录

2030.汉字统计

Problem Description
统计给定文本文件中汉字的个数。
Input
输入文件首先包含一个整数n,表示测试实例的个数,然后是n段文本。
Output
对于每一段文本,输出其中的汉字的个数,每个测试实例的输出占一行。
[Hint:]从汉字机内码的特点考虑~
Sample Input
2
WaHaHa! WaHaHa! 今年过节不说话要说只说普通话WaHaHa! WaHaHa!
马上就要期末考试了Are you ready?
Sample Output
14
9

分析:统计汉字的个数要注意一下两点:
(1)汉字的ASCII码为负值,所以可以根据这一点来统计汉字的个数;
(2)由于汉字在Ascll码中是两个字节,所以最后的结果要除以2;

#include <stdio.h>
#include <string.h>

void Character(){
	int n,i,count,length;
	char str[1000];
	scanf("%d",&n);
	getchar();
	while(n--){
		count=0;
		gets(str);
		length=strlen(str);
		for(i=0;i<length;i++){
			//汉字的ASCII码是负值
			if(str[i]<0) count++;
		}
		//汉字在Ascll码中是两个字节,所以最后的结果要除以2
		printf("%d\n",count/2);
	}
}

2031.进制转换

Problem Description
输入一个十进制数N,将它转换成R进制数输出。
Input
输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=16, R<>10)。
Output
为每个测试实例输出转换后的数,每个输出占一行。如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。
Sample Input
7 2
23 12
-4 3
Sample Output
111
1B
-11

分析:对于r进制转换,可以使用除几取余法。例如输入的数为22 4,即将9转换为4进制,具体步骤如下:
(1)22%4=2
(2)22/4=5
(3)5%4=1
(4)5/4=1
(5)1%4=1
(6)1/4=0;
最后相除的结果为0时停止计算,将求余数得到的结果自下而上输出(1->1->2),得到的112即为所求的结果。若要转换的数为负数,即-22,在112前面加上“-”即可。

#include <stdio.h>

void ScaleConvert(){
	//n表示要被转换的数,m表示要转换成的进制数 
	int n,r,i,j,temp,sign;
	char str[200];
	while(scanf("%d%d",&n,&r)){
		if(r<2 || r>16) {
			printf("m的取值范围为[2,16]之间的整数!\n");
			continue;
		}
		//n为0,直接输出0即可 
		if(n==0){
			printf("%d\n",0);
			continue;
		}
		//若n为负数,则先求其绝对值转换的结果,然后再在结果前面加上"-"即可 
		if(n<0){
			sign=-1;
			n=-n;
		}else{
			sign=1;
		}
		i=0;  
		while(n>0){
			temp=n%r;
			//若temp>=10,此时需要用到A、B...等来分别表示10、11... 
			if(temp>=10){
				str[i]=temp-10+'A';
			}else{
				str[i]=temp+'0';
			}
			i++;
			n/=r;
		}
		if(sign==-1) printf("-");
		//逆序输出str中的内容 
		for(j=i-1;j>=0;j--){
			printf("%c",str[j]);
		}
		printf("\n");
	}
}

2032.杨辉三角

Problem Description
还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Input
输入数据包含多个测试实例,每个测试实例的输入只包含一个正整数n(1<=n<=30),表示将要输出的杨辉三角的层数。
Output
对应于每一个输入,请输出相应层数的杨辉三角,每一层的整数之间用一个空格隔开,每一个杨辉三角后面加一个空行。
Sample Input
2 3
Sample Output
1
1 1

1
1 1
1 2 1

分析:以二维数组arr来存储杨辉三角,注意一下两种位置的元素即可:
(1)主对角线和第一列的元素均为1 ,即arr[i][0]=arr[i][i]=1;
(2)其余元素均为上一行相邻元素和左上角相邻元素之和 ,即arr[i][j]=arr[i-1][j-1]+arr[i-1][j];

#include <stdio.h>

void YanghuiTriangle(){
	int n,i,j;
	int arr[30][30]={0};
	while(scanf("%d",&n)!=EOF){
		if(n<=0 || n>=31){
			printf("n的取值范围为[0,30]之间的整数!\n");
			continue;
		}
		for(i=0;i<n;i++){
			for(j=0;j<=i;j++){
				//若以二维数组来存储杨辉三角,则主对角线和第一列的元素均为1 
				if(i==j) arr[i][j]=1;
				if(j==0) arr[i][j]=1;
				//其余元素均为上一行相邻元素和左上角相邻元素之和 
				if(i!=j && j!=0){
					arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
				}
				printf("%d ",arr[i][j]);
			}
			printf("\n");
		}
		printf("\n");
	}
}

2033.人见人爱A+B

Problem Description
HDOJ上面已经有10来道A+B的题目了,相信这些题目曾经是大家的最爱,希望今天的这个A+B能给大家带来好运,也希望这个题目能唤起大家对ACM曾经的热爱。
这个题目的A和B不是简单的整数,而是两个时间,A和B 都是由3个整数组成,分别表示时分秒,比如,假设A为34 45 56,就表示A所表示的时间是34小时 45分钟 56秒。
Input
输入数据有多行组成,首先是一个整数N,表示测试实例的个数,然后是N行数据,每行有6个整数AH,AM,AS,BH,BM,BS,分别表示时间A和B所对应的时分秒。题目保证所有的数据合法。
Output
对于每个测试实例,输出A+B,每个输出结果也是由时分秒3部分组成,同时也要满足时间的规则(即:分和秒的取值范围在0~59),每个输出占一行,并且所有的部分都可以用32位整数表示。
Sample Input
2
1 2 3 4 5 6
34 45 56 12 23 34
Sample Output
5 7 9
47 9 30

分析:在编写代码时考虑时、分、秒的转换规则即可。

#include <stdio.h>

void AAddB(){
	int AH,AM,AS,BH,BM,BS;
	int n,hour,minute,second;
	scanf("%d",&n);
	while(n--){
		hour=minute=second=0;
		scanf("%d%d%d%d%d%d",&AH,&AM,&AS,&BH,&BM,&BS);
		if(AH<0 || BH<0 || 
		   AM<0 || AM>=60 || 
		   AS<0 || AS>=60 ||
		   BM<0 || BM>=60 || 
		   BS<0 || BS>=60){
			printf("输入的时间不合法!\n");
			continue;
		}
		//计算秒 
		if(AS+BS>=60){
			second=(AS+BS)-60;
			minute++;
		}else{
			second=AS+BS;
		}
		//计算分
		if(AM+BM+minute>=60){
			minute=(AM+BM+minute)-60;
			hour++;
		}else{
			minute=AM+BM+minute;
		}
		//计算时 
		hour=hour+AH+BH;
		printf("%d %d %d\n",hour,minute,second);
	}
} 

2034.人见人爱A-B

Problem Description
参加过上个月月赛的同学一定还记得其中的一个最简单的题目,就是{A}+{B},那个题目求的是两个集合的并集,今天我们这个A-B求的是两个集合的差,就是做集合的减法运算。(当然,大家都知道集合的定义,就是同一个集合中不会有两个相同的元素,这里还是提醒大家一下)
呵呵,很简单吧?
Input
每组输入数据占1行,每行数据的开始是2个整数n(0<=n<=100)和m(0<=m<=100),分别表示集合A和集合B的元素个数,然后紧跟着n+m个元素,前面n个元素属于集合A,其余的属于集合B. 每个元素为不超出int范围的整数,元素之间有一个空格隔开.
如果n=0并且m=0表示输入的结束,不做处理。
Output
针对每组数据输出一行数据,表示A-B的结果,如果结果为空集合,则输出“NULL”,否则从小到大输出结果,为了简化问题,每个元素后面跟一个空格.
Sample Input
3 3 1 2 3 1 4 7
3 7 2 5 8 2 3 4 5 6 7 8 
0 0
Sample Output
2 3 
NULL

分析:注意到输出时应该从小到大输出,下面的代码中采用的是快速排序。

#include <stdio.h>

//快速排序(递增) 
int Partition(int arr[],int s,int t){
	int i=s,j=t;
	int temp=arr[i];
	while(i<j){
		while(j>i && arr[j]>=temp) j--;
		arr[i]=arr[j];
		while(j>i && arr[i]<=temp) i++;
		arr[j]=arr[i];
	}
	arr[i]=temp;
	return i;
}

void QuickSort(int arr[],int s,int t){
	int i;
	if(s<t){
		i=Partition(arr,s,t);
		QuickSort(arr,s,i-1);
		QuickSort(arr,i+1,t);
	}
}

void ASubB(){
	int arr1[100],arr2[100],res[100];
	int n,m,i,j,flag,index;
	while(scanf("%d%d",&n,&m)!=EOF){
		//如果n=0并且m=0表示输入的结束,不做处理
		if(n==0 && m==0){
			break;
		}
		memset(arr1,0,sizeof(arr1));
		memset(arr2,0,sizeof(arr2));
		memset(res,0,sizeof(res));
		for(i=0;i<n;i++)	scanf("%d",&arr1[i]);
		for(i=0;i<m;i++)	scanf("%d",&arr2[i]);	
		index=0;
		for(i=0;i<n;i++){
			flag=1;
			for(j=0;j<m;j++){
				if(arr1[i]==arr2[j]){
					flag=0;
					break;
				}
			}
			if(flag) res[index++]=arr1[i];
		}
		if(index==0){
			printf("NULL\n");
		}else{
			QuickSort(res,0,index-1);
			for(i=0;i<index;i++){
				printf("%d ",res[i]);
			}
			printf("\n");
		}
	}
}
上一篇:使用js获取当前的时间日期


下一篇:5.8 面向对象程序设计C++课后习题