c刷题(四)

获得月份天数

获得月份天数_牛客题霸_牛客网

c刷题(四)_第1张图片

这道题可以用switch case语句解,不过这道题更简单的方法是数组,关键点在于判断是否为闰年。 

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include
int year_run(int n)
{
    if (((n % 4 == 0) && n % 100 != 0)||(n % 400 == 0))
        return 1;
    else
        return 0;
}
int main()
{
    int y = 0;
    int m = 0;
    int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 
    while(scanf("%d%d", &y, &m) != EOF)//多组输入
    {
        assert(m>0&&m<13);//断言
        int day = days[m];
        if(year_run(y) && m==2)
            day++;
            printf("%d\n",day);
    }
    return 0;
}

 判断闰年和2月可以合并成一条语句用&&操作符连结,将数组下标0设置成0与月份对应,也可以添加断言是程序更加健壮。

判断字母

判断是不是字母_牛客题霸_牛客网

c刷题(四)_第2张图片

在用getchar或scanf读取字母的时候,我们的回车键(\n)会被保存下来,导致输出错误结果。所以这道题的关键是清理\n

#include 

int main ()
{
 int ch=0;
 while(scanf("%c\n",&ch)!=EOF)
//while(ch = getchar() !=EOF)//读取失败返回-1
 {
     if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
     
     {printf("%c is an alphabet.\n",ch);}
     else
     {printf("%c is not an alphabet.\n",ch);}
     //getchar();
 }
return  0;
}

字母大小写转换 

 字母大小写转换_牛客题霸_牛客网

利用ascii码的一一映射关系解决,也可以使用c语言的库函数——toupper(转大写)tolower(转小写)来转化。

#include 

int main() {
    char ch;
    while (scanf("%c", &ch) != EOF) { //加\n会使结果错位
        if (ch <= 'z' && ch >= 'a')
            printf("%c\n", ch - 32);
        if (ch <= 'Z' && ch >= 'A')//其他字符忽略掉了题目没做要求
            printf("%c\n", ch + 32);//不排除其他字符
        getchar();//去\n
    }
    return 0;
}
//库函数
#include
#include 

int main()
{
    int ch = 0;
    while((ch=getchar()) != EOF)
    {
        if(islower(ch))//判断小写函数
        {
            printf("%c\n", toupper(ch));
        }
        else
        {
            printf("%c\n", tolower(ch)); 
        }
        getchar();
    }
    return 0;
}

别忘了清理缓冲区!

网购

网购_牛客题霸_牛客网c刷题(四)_第3张图片

并不难,主要是想分享用0和1表示优惠券这个妙处,省去了多余的判断。

#include 

int main() {
    double p;
    int m, n,discount;
    scanf("%lf %d %d %d", &p, &m, &n, &discount);
    if (m == 11 && n == 11)
    {
        p = p * 0.7 - discount * 50;
    }
    else if(m == 12 && n == 12)
        p = p * 0.8 - discount * 50;
    if (p < 0)
        p = 0;
    printf("%.2lf", p);
    return 0;
}

下列程序段的输出结果

unsigned long pulArray[] = {6,7,8,9,10};
unsigned long *pulPtr;
pulPtr = pulArray;
*(pulPtr + 3) += 3;
printf("%d,%d\n",*pulPtr, *(pulPtr + 3));

访问第4个元素的地址并解引用对值+3然后赋值给第四个pulArray[3]这个变量,可以理解为pulArray[0+3] = pulArray[0+3]+3。打印结果为6,12

字符逆序 

字符逆序__牛客网

c刷题(四)_第4张图片

这道题用scanf输入数据显然是不合理的,我们可以用gets函数输入一行字符串,结束标志为\n,然后记录数组首尾指针进行交换(不包括\0)。 

#include 
#include
int main() {
   char arr[10001] = {0};
   gets(arr);
   int num = strlen(arr)-1;//下标
   char* left = arr;
   char* right = arr+num;
   while(left

 自幂数

求出0~100000之间的所有“水仙花数”并输出。

要点:灵活运用pow函数求次方并记录每一位数求相应位数的次方数。

int water(int c,int num)//递归 
{
	if (c < 10)
	{
		return (int)pow(c, num);
	}
	int n = water(c / 10,num);
	return (int)pow(c % 10, num) + n;
}int count_num(int i)
{
	int num = 0;
	if (i < 10)
	{
		return ++num;
	}
	return 1 + count_num(i / 10);//记录次数
}
int main()
{
	int i = 0;
	for (i = 0; i < 100000; i++)
	{
		//计算位数

		if (i == water(i,count_num(i)))
			printf("%d ", i);
	}
	return 0;
}

a的前n项之和 

求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字,例如:2+22+222+2222+22222

 找规律:前面的数乘以10+a为后面的一项。那第一项就是0*10+a。

int main()
{
	int a = 0;
	int n = 0;
	int i = 0;
	int sum = 0;
	int tmp = 0;


	scanf("%d%d", &a, &n);
	for(i=0; i

最小公倍数

方法一:选两个数较大值记为x,不断++直到x能整除二者。

方法二:辗转相除法求最大公倍数(k)然后利用公式 m*n/k 

方法三:选两个数较小值按倍数递增去试除二者,直至都能被整除。

前面两个方法之前已经实现过了,我们来看第三个方法:

	int m, n;
	int i = 1;
	while (scanf("%d %d", &m, &n) == 2)
	{
		if (m > n)
		{
			int tmp = m;
			m = n;
			n = tmp;
		}
		for (i = 1; m * i % n != 0; i++)
		{
			;
		}
		printf("%d\n", m * i);
	}

提示:如果数据过大可以将int改为long类型

  倒置字符串

倒置字符串__牛客网

c刷题(四)_第5张图片

思路:单词倒置+整体倒置(可以改变顺序),每个单词倒置同样需要记录首尾指针,尾为空格-1,整体结束条件为\0注意最后一个单词的结束条件也为\0.

#include 
#include 
#include 
void reverse(char* left,char* right)
{
    assert(left && right);//断言
    while(left

你可能感兴趣的:(算法)