杭电oj刷题C语言答案+思路

作为接触C语言不久的新人来说,确实有很多没想到的地方,不少方法是暴力求解,代码量长,方法麻烦,一些题目还是有借鉴大佬的答案,请多谅解。一些题目有我的笔记。如有错误以及更好的见解,请理性讨论。如果对你有帮助,请点个赞吧~  点赞+评论+收藏+关注~ 缓慢更新中……


目录

第一阶段

一、输入输出练习

1000

1089

1090  

1091

1092

1093

1094

四、水题

2025 查找最大元素

2026 首字母变大写

2027 统计元音

2028 最小公倍数

2029 Palindromes _easy version

2030 汉字统计

2032杨辉三角

2040 亲和数

2054

2055

第二阶段

一、字符串

2072

 2081

2093

1004

2057

二、简单数学题

2031 进制转换

2033 人见人爱A+B

2070 Fibbonacci数列

2071

2075

2089

2097

2098

2099

三、汉诺塔

1995

1996


第一阶段

一、输入输出练习

1000

#include <stdio.h>
int main()
{
	int A=0;
	int B=0;
	while(scanf("%d%d",&A,&B)!=EOF)
		printf("%d\n",A+B);
return 0;
 } 

1089

#include <stdio.h>
int main()
{
	int A=0;
	int B=0;
	while(scanf("%d%d",&A,&B)!=EOF)
	{		
		printf("%d\n",A+B);		
	}
	
return 0;
 } 

1090  

#include <stdio.h>
int main()
{
	int a,b;
	int n;
	scanf("%d",&n);
	int i=0,j=0;
	while(i<n)
	{
		scanf("%d%d",&a,&b);
		printf("%d\n",a+b);
		i+=1;
	}

	
return 0; 
 } 

1091

#include <stdio.h>
int main()
{
	int a=1;
	int b=1;
	while(scanf("%d%d",&a,&b)!=EOF&&a!=0||b!=0)
	{
		printf("%d\n",a+b);
	}
return 0; 
 } 

1092

改了好几次,注意格式

#include <stdio.h>
int main()
{
	int n = 0,a = 0,sum = 0;
	while(scanf("%d",&n) != EOF&&(n!=0))
	{
		sum = 0;
		while(n--){
			scanf("%d",&a);
			sum += a;
		}
		printf("%d\n",sum);
	}
return 0; 
 } 

1093

#include <stdio.h>
int main()
{
   int a = 0; 
    int b = 0, s = 0;
    int c=0;

    scanf("%d", &a);

    while (a--)
    {
        scanf("%d", &b);
        s = 0;
        while (b--)
        {
            scanf("%d", &c);
            s += c;
        }
        printf("%d\n", s);

    }

    return 0;
}

1094

#include <stdio.h>
int main()
{
	int n=0;
	int b=0,s=0;
	while(scanf("%d",&n)!=EOF)
	{
		s=0;
	while(n--)
	{
		
		scanf("%d",&b);
		s+=b;
	
	}
		printf("%d\n",s);
	}
return 0;
 } 

四、水题

2025 查找最大元素

比较的是输入字符串内的最大字符,找到它之后。在它后面直接输出(max),再接着输出后续字符。

#include <stdio.h>
#include <string.h>
 
int main()
{
	char a[100]="0";
	int i=0;
	while(scanf("%s",&a)!=EOF)
	{
		char m='A';
		int size=strlen(a);
		for(i=0;i<size;i++)
		{
			if(a[i]>=m)
			{		
				m=a[i];
			}
		}
		for(i=0;i<size;i++)
		{
			putchar(a[i]);
			if(a[i]==m)
				printf("(max)");
		}
		printf("\n");

	}
	
	return 0;
 } 

2026 首字母变大写

scanf不接受空格

gets接受

#include <stdio.h>
#include <string.h>
int main()
{
	char a[100]="0";
	int i=0;
	while(gets(a))
	{
		int size=strlen(a);
		a[0]=a[0]-32;
		for(i=0;i<size;i++)
		{
			if((a[i]==' ')&&(a[i+1]!='\0') )
			{
				a[i+1]=a[i+1]-32;
			}
		}
		puts(a);
	}
	return 0;
 }

2027 统计元音

#include <stdio.h>
#include <string.h>
int main()
{
    char a[100]="0";
	int i=0,n=0;
	while(scanf("%d",&n)!=EOF)
	{
		getchar();
		while(n--)
		{
			gets(a);
			int a_count=0,i_count=0,e_count=0,o_count=0,u_count=0;
			int size=strlen(a);
		for(i=0;i<size;i++)
		{
			if(a[i]>='A'&&a[i]<='Z')
				a[i]=a[i]+32;
			if(a[i]=='a')
				a_count++;
			if(a[i]=='e')
				e_count++;
			if(a[i]=='i')
				i_count++;
			if(a[i]=='o')
				o_count++;
			if(a[i]=='u')
				u_count++;					
		}
		if(n!=0)
		printf("a:%d\ne:%d\ni:%d\no:%d\nu:%d\n\n",
		        a_count,e_count,i_count,o_count,u_count);
		else
			printf("a:%d\ne:%d\ni:%d\no:%d\nu:%d\n",
		        a_count,e_count,i_count,o_count,u_count);
		}
	}

return 0;
}

2028 最小公倍数

#include <stdio.h>
int main()
{
	int n=0;
	while(scanf("%d",&n)!=EOF)
	{
		int a[n]={0};
		int sum=1;
		int i=0,m=0,k=0,r=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
			sum=a[i]*sum;
		}
		for(i=0;i<n-1;i++)
		{
			m=a[i];
			k=a[i+1];
			while(k)
			{				
				r=m%k;
				m=k;
				k=r;				
			}
			a[i+1]=m;	
		}
		printf("%d\n",sum/m);
	}
	
	return 0;
 } 

2029 Palindromes _easy version

#include <stdio.h>
#include <string.h>
int main()
{
	int n = 0;
	int i = 0, j = 0;
	while (scanf("%d", &n) != EOF)
	{
		getchar();
		while (n--)
		{
			char a[100] = "0";
			int temp = 1;
			scanf("%s", a);
			int size = strlen(a);
			for (i = 0,j=size-1; i <j; i++,j--)
			{
				if (a[i] != a[j])
					temp = 0;
			}
			if (temp == 1)
				printf("yes\n");
			else
				printf("no\n");


		}
	}

	return 0;
}

2030 汉字统计

汉字内码,每个汉字为二进制,两个字节构成,每个字节(8bit)的最高位为1。计算机中是以补码存储的,汉字内码转为补码时,每个字节最高位为符号位1,即每个字节均为负数。所以只要找出负数然后除以2就能得到汉字的个数。

#include <stdio.h>
#include <string.h>
int main()
{
	int n = 0;
	int i = 0;
	char a[1000] = "0";
	while (scanf("%d", &n) != EOF)
	{
		getchar();
		while (n--)
		{
			int count = 0;
			gets(a);
			int size = strlen(a);
			for (i = 0; i < size; i++)
			{
				if (a[i]<0)
				{
					count++;
				}
			}
			printf("%d\n", count/2);
		}
	}
	return 0;
}

2032杨辉三角

#include <stdio.h>
#include <string.h>
int main()
{
	int n = 0;
	int i = 0, j = 0;
	int a[100][100] = { 0 };
	while (scanf("%d", &n)!=EOF)
	{
		for (i = 1; i <= n; i++)
		{
			for (j = 1; j <= i; j++)
			{
				if (j == 1)
					a[i][j] = 1;
				else if (i == j)
				{
					a[i][j] = 1;

				}
				else
					a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
			}
	    }
			for (i = 1; i <= n; i++)
			{
				for (j = 1; j <= i; j++)
				{
					if (i != j)
					{
						printf("%d ", a[i][j]);
					}
					else
					{
						printf("%d\n", a[i][j]);
					//	break;
					}
				}
			}
			printf("\n");
		
	}
	return 0;
}

2040 亲和数

#include <stdio.h>
#include <string.h>
int su(int a)
{
	int i = 0;
	int sum = 0;
	for (i = 1; i < a; i++)
	{
	if (a % i == 0)
		sum = sum + i;
	}
	return sum;
	

}
int main()
{
	int n = 0;
	while (scanf("%d", &n) != EOF)
	{
		while (n--)
		{
			int a = 0, b = 0;
			scanf("%d%d", &a, &b);
			int m = su(a);
			int n = su(b);
			if (m == b && n == a)
				printf("YES\n");
			else
				printf("NO\n");
		}
	}
	return 0;
}

2054

Strstr();用于检验目标字符串中第一次出现某个字符或者某段字符串的位置;

头文件:#include <string.h>

显示第一次找到,要查找的字符串,以及后面的字符串。大小写敏感匹配后截取。
strstr()函数用来检索子串在字符串中首次出现的位置,其原型为:
    char *strstr( char *str, char * substr );

【参数说明】str为要检索的字符串,substr为要检索的子串。

【返回值】返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL

#include <stdio.h>
#include <string.h>
void s(char *a)
{
	
	int i = 0;
	int size = strlen(a);
	if (strstr(a, "."))
	{
		for (i = size - 1; a[i] == '0'; i--)
		{
			a[size - 1] = '\0';//如果小数点后都是0,就去掉。还剩下小数点
			size--;
		}
	}
	if (a[size - 1] == '.')//去掉剩下的小数点
	{
		a[size - 1] = '\0';
	}
}
int main()
{
	char a[10000];
	char b[10000];
	while (scanf("%s %s", a, b) != EOF)
	{
		s(a);
		s(b);
		if (!strcmp(a, b))
		{
			printf("YES\n");
		}
		else
			printf("NO\n");
	}

	return 0;
}

2055

#include <stdio.h>
#include <string.h>
int main()
{
	int n = 0;
	int sum = 0;
	while (scanf("%d", &n) != EOF)
	{
		while (n--)
		{
			char a;
			int b; 
			getchar();
			scanf("%c%d", &a,&b);
			if (a >= 'A' && a <= 'Z')			
				sum = a - 65 + 1 ;		
			else if(a>='a'&&a<='z')
				sum = -1*(a - 97 + 1);			
			printf("%d\n", sum+b);
			
		}
	}
	return 0;
}

第二阶段

一、字符串

2072

#include<stdio.h>
#include<string.h>
int main(){
    char str[1000];//输入的句子
	char s[1000][1000];//定义一个存单词的二维数组
while(strcmp(gets(str),"#")!=0)
{
    	int a=0,b=0,i=0;//a为行,b为列
    	while(i<strlen(str))
        {//遍历输入的句子
			if(str[i]==' ')
				i++;//如果开头为空格,则后移,直到第一个单词出现
			else
            {
				while(str[i]!=' ' && str[i]!='\0')
                {//既不是空格也不是结尾标识符,即如果出现了单词
					s[a][b]=str[i];//把单词放到二维数组中去,按行存储一行一个单词
					i++;
					b++;//行数a不变,列数b和句子中的i均后移一位
				}
				//遇到空格或者结尾则跳出循环,即表示一个单词存储完毕
				s[a][b]='\0';//结尾加上终止符,不然下面取字符串会出错
				a++;//换行存储新的单词
				b=0;//列数重新置0,即从下一行开头重新存储
			}
		}
		
		int m,n;
		int sum = 0;
		for(m=0; m<a; m++)
        {//循环遍历每行单词
			int flag = 0;
			for(n=m+1; n<a; n++)
            {
				if(strcmp(s[m],s[n])==0)
                {//将二维数组中的每行单词进行对比
					flag = 1;//若相同则flag置1
				}
			}
			if(flag!=1)
            {//不等于则表示单词不同
				sum++;//不同单词数加一
			}
		}
		printf("%d\n",sum);
	}
return 0;
}

 2081

#include <stdio.h>
#include <string.h>
int main()
{
	int n = 0;
	while (scanf("%d", &n) != EOF)
	{
		
		while (n--)
		{
			getchar();
			char a[12] = "0";
			scanf("%s", &a);
			printf("6");
			int i = 0;
			for (i = 6; i < 11; i++)
			{
				printf("%c", a[i]);
			}
			printf("\n");
		}
	}

 return 0;
}

2093

#include <stdio.h>
int main()
{
	int n,space=0;
	char a;
	while (scanf("%c%d", &a, &n) == 2 && a != '@')
	{
		getchar();
		if(space>0)
			printf("\n");
		int i, j, k;
		if (n == 1)
			printf("%c\n", a);
		else
		{
			for (i = 1; i < n; i++)
			{
				for (j = 1; j < n + i; j++)
				{
					if (j == n - i + 1 || j == n + i - 1)
						printf("%c", a);
					else
						printf(" ");
				}
				printf("\n");
			}
			for (i = 1; i <= 2 * n - 1; i++)
			{
				printf("%c", a);
			}
			printf("\n");
		}
		space++;
	}
		


	return 0;
}

1004

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    int n = 0, i=0, j=0;
    int max = 0;
    char a[1000][16];
    int* size;
    while (scanf("%d", &n) && n != 0)
    {
        
        size = (int*)malloc(sizeof(int) * n);
        for (i = 0; i < n; i++)
        {
            scanf("%s", &a[i]);
        }

     

        for (i = 0; i < n; i++)
        {
            size[i]=1;
            for (j = i + 1; j < n; j++)
            {
                if (strcmp(a[i], a[j]) == 0)
                {
                    size[i]++;

                }
            }
        }
        max = size[0];
        int k = 0;
        for (i = 0; i < n; i++)
        {
            if (size[i]> max) 
            {
                max = size[i];
                k = i;
            }
        }
        printf("%s\n", a[k]);
    }
    return 0;
}

2057

要使用64位整数  __int64 (英文输入下,两个“_”),输出用printf("%I64d\n",a[n]);

#include <stdio.h>
int main()
{
   
    while (1)
    {
        __int64 a, b, sum;
        scanf("%I64X %I64X", &a, &b);
        sum = a + b;
        if (sum > 0)
            printf("%I64X\n", sum);
        else
            printf("-%I64X\n", -sum);
    }
    return 0;
}

二、简单数学题

2031 进制转换

要先把负数换成正数

#include <stdio.h>
#include <math.h>
int main()
{
	int N1, R;
	char a[] = "ABCDEF";
	while (scanf("%d%d", &N1,&R) ==2)
	{
		getchar();
		int i = 0,c=0;
		int N = abs(N1);
		int res[33];
		while (N)
		{
			res[i] = N % R;
			N = N / R;			
			i++;
		}

		if (N1 < 0)
		{
			printf("-");
		}
		int j;
		for (j = i-1; j >= 0; j--)
		{
			if (R > 10 && res[j] >= 10)
			{
				if (res[j] < 15)
				{
					c = res[j] % 5;
				}
				else
					c = 5;
				printf("%c", a[c]);

			}
			else
				printf("%d", res[j]);
		}
		printf("\n");

	}
	return 0;
}

2033 人见人爱A+B

博主使用的方法很麻烦......

#include <stdio.h>
#include <math.h>
int main()
{
	
	int n = 0;
	while (scanf("%d", &n) != EOF)
	{
		while (n--)
		{
			int a[3] = { 0 }, b[3] = { 0 };
			int i = 0;
			for (i = 0; i < 3; i++)
			{
				scanf("%d", &a[i]);
			}
			for (i = 0; i < 3; i++)
			{
				scanf("%d", &b[i]);
			}

			int c[3] = { 0 };
			int e[3] = { 0 };
			for (i = 2; i >=0 ; i--)
			{
				c[i] = a[i] + b[i];
				int flag = 0;
				int d = 0;
				if (i > 0)
				{
					if (c[i] > 59)
					{
						d = c[i];
						c[i]%=60;
						d /= 60;
						//int j = i;						
						e[i - 1] += d;
					}					
				}
			}
			for (i = 0; i < 2; i++)
			{
				c[i] += e[i];
			}
			printf("%d %d %d\n", c[0], c[1], c[2]);
		}


	}
	return 0;
}

2070 Fibbonacci数列

要使用64位整数  __int64 (英文输入下,两个“_”),输出用printf("%I64d\n",a[n]);

#include<stdio.h>
int main() 
{
	int i, j;
	__int64 a[10000];
	while (scanf("%d", &i) != EOF&&i!=-1) 
	{
		a[0] = 0; 
		a[1] = 1;
		for (j = 2; j <= i; j++) 
		{
			a[j] = a[j - 1] + a[j - 2];
		}
		printf("%I64d\n", a[i]);
	}
	return 0;

}

2071

#include <stdio.h>
int main()
{
	int t = 0, n = 0;
	while (scanf("%d", &t) != EOF)
	{
		while (t--)
		{
			scanf("%d", &n);
			float h[100] = { 0 };
			int i = 0;
			float max = 0;
			while (n--)
			{
				scanf("%f", &h[i]);
				if (h[i] > max)
				{
					max = h[i];
				}
				i++;
			}
			printf("%.2f\n", max);
		}
	}

	return 0;
}

2075

#include <stdio.h>
int main()
{
	int t = 0, a = 0, b = 0;
	while (scanf("%d", &t) != EOF)
	{
		while (t--)
		{
			scanf("%d%d", &a, &b);
			if (a % b == 0)
			{
				printf("YES\n");
			}
			else
				printf("NO\n");
		}
	}

	return 0;
}

2089

参考了大佬的答案,这确实是道数学题,需要找出一个等差数列的公式,更好的答案就不在此列出了,因为这个等差公式还是蛮难想到的。还需要考虑到运行时间。 

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

int s[1000000];
int main() 
{
    int n, m, i, count;
    char stri[10];
    for (i = 0; i <= 1000000; i++) 
    {
        itoa(i, stri, 10);
        if (strstr(stri, "4") == NULL && strstr(stri, "62") == NULL) 
        { 
            s[i] = 1;
        }
        else 
        { 
            s[i] = 0; 
        }
    }
    while (scanf("%d %d", &n, &m) != EOF) 
    {
        if (n == 0 && m == 0) 
        { 
            break;
        }
        count = 0;

        for (i = n; i <= m; i++) 
        {
            count += s[i];
        }
        printf("%d\n", count);
    }

}

2097

#include <stdio.h>

int change(int a,int s)
{
	
	int g = 0, sum = 0;
	while (a)
	{
		g = a % s;
		a = a / s;
		sum = sum + g;
	}
	return sum;
}
int main()
{
	int a = 0;
	while (scanf("%d", &a) != EOF && a != 0)
	{
		
		if (change(a, 10) ==  change(a, 12) && change(a, 16) == change(a, 10))
			printf("%d is a Sky Number.\n", a);
		else
			printf("%d is not a Sky Number.\n", a);
	}
	return 0;
}

2098

 博主用的也有点麻烦......

#include <stdio.h>
#include <math.h>

int main()
{
	int a = 0,i = 0,j=0;
	while (scanf("%d", &a) != EOF && a != 0)
	{
		a = abs(a);
		int c[10000] = { 0 };
		int count = 0;
		for (j = 2; j <= a; j++)
		{
			for (i = 2; i < sqrt(j); i++)
			{
				if (j % i == 0)
				{
					break;
				}
			}
			if (i > sqrt(j))
			{
				c[count] = j;
				count++;
			}
		}
		int flag = 0;
		for (i = 0; i < count-1; i++)
		{
			for (j = i+1; j < count; j++)
			{
				if (c[i] + c[j] == a)
				{
					flag++;
				}
			}
		}
		printf("%d\n", flag);
	}
	return 0;
}

2099

#include <stdio.h>
#include <math.h>

int main()
{
	int a = 0, b = 0;
	while (scanf("%d%d", &a, &b) != EOF && a != 0 && b != 0)
	{
		int i = 0, flag = 1;
		for (i = 0; i < 100; i++)
		{		

			if ((a * 100 + i)% b == 0)
			{
				if (flag == 0)
					printf(" ");
				printf("%02d", i);
				flag = 0;
				
			}
		}
		printf("\n");
	}
	return 0;
}

三、汉诺塔

1995

找规律,利用递归实现

当有n个盘子时,1号盘子移动2^(n-1),

2号盘子移动2^(n-2)......

n号盘子移动2^(n-n)次;

#include <stdio.h>

__int64 re(int n, int k)
{
	if (n == k)
		return 1;

	return re(n - 1, k)*2;

}
int main()
{
	int t = 0;
	while (scanf("%d", &t) != EOF)
	{
		while (t--)
		{
			int n = 0, k = 0;
			scanf("%d%d", &n, &k);
			printf("%I64d\n",re(n, k));
		}
	}
return 0;
}

1996

一样可以找规律利用递归实现:3^1=3, 3^3=27......

#include <stdio.h>

__int64 re(int n)
{
	if (n == 1)
		return 3;

	return re(n - 1)*3;

}
int main()
{
	int t = 0;
	while (scanf("%d", &t) != EOF)
	{
		while (t--)
		{
			int n = 0, k = 0;
			scanf("%d", &n);
			printf("%I64d\n",re(n));
		}
	}
return 0;
}

2064

递归,找规律。

a[1]=2,a[2]=8,a[3]=26,a[4]=80,可以看出从2开始都满足a[n]=3*a[n-1]+2

#include <stdio.h>
_int64 num(int n)
{
	if (n == 1)
	{
		return 2;
	}
	else 
	{
		return (3 * num(n-1) + 2);
	}
}

int main()
{
	_int64 a;
	int n;
	while (scanf("%d", &n) != EOF)
	{
		a = num(n);
		printf("%I64d\n", a);
	}
}

2077

对于最大的那块盘子而言,他只需要被移动两次。剩下的n-1个盘子还和之前一样。所以把最大的盘子当做第三种情况考虑。有借鉴大佬的答案……汉诺塔不会玩啊……

#include <stdio.h>
_int64 num(int m, int N)
{
	if (m == 1)
		return 2;
	else if (m == N)
		return(num(m - 1, N) + 2);
	else
		return(3 * num(m - 1, N) + 2);
}
int main()
{
	_int64 a;
	int n, m;
	while (scanf("%d", &n) != EOF)
	{
		while (n--)
		{
			scanf("%d", &m);
			int N  = m;
			a = num(m,N);
			printf("%I64d\n", a);
		}
	}


	return 0;
}

2175

第一个输入的是盘子个数,第二输入的是第m次。

参考的大佬的答案……

第一层移动次数全为奇数以外,每一层的移动的次数都是上一层移动次数倍数,将输入的移动次数一路除到底,除的次数(s)就是第几号盘子

#include<stdio.h>

int main() 
{

    int n;
    __int64 m;
    int s;
    while (scanf("%d%I64d", &n, &m)&&(n+m)) 
    {      
        s = 1;
        while (m % 2 == 0) {
            m /= 2;
            s++;
        }
        printf("%d\n", s);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值