杭电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 
int main()
{
	int A=0;
	int B=0;
	while(scanf("%d%d",&A,&B)!=EOF)
		printf("%d\n",A+B);
return 0;
 } 

1089

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

1090  

#include 
int main()
{
	int a,b;
	int n;
	scanf("%d",&n);
	int i=0,j=0;
	while(i

1091

#include 
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 
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 
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 
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 
#include 
 
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=m)
			{		
				m=a[i];
			}
		}
		for(i=0;i

2026 首字母变大写

scanf不接受空格

gets接受

#include 
#include 
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

2027 统计元音

#include 
#include 
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='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 
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

2029 Palindromes _easy version

#include 
#include 
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 

2030 汉字统计

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

#include 
#include 
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 
#include 
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 
#include 
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

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

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

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

#include 
#include 
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 
#include 
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
#include
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

 2081

#include 
#include 
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 
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 
#include 
#include 
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 
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 
#include 
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 
#include 
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
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 
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 
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
#include
#include

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 

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 
#include 

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 
#include 

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 

__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 

__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 
_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 
_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

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;
}

你可能感兴趣的:(杭电oj,c语言,算法)