12月26日学习记录

     今天把好久没登录的刷题网站重新上去了一遍写一一点点简单的代码,发现很多东西都已经忘掉了,现在把写过的题目都记录下来,留作笔记。

题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。
例如,输入”They are students.”和”aeiou”,
则删除之后的第一个字符串变成”Thy r stdnts.”。

其实这个题目很简单,关键是要想清楚两个字符型数组之间关系,另外我在写的过程中发现字符型数组不能直接赋值给字符型数组,可能是我上课没认真听还是我的写法有问题,后来只能用整型数组去记录然后以%c的形式输出就行。

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

char ch1[100],ch2[100];
int main()
{
    gets(ch1);
    gets(ch2);//读取字符串
    int lenA,lenB;//计算字符串的长度
    lenA = strlen(ch1);
    lenB = strlen(ch2);

    int i,j;
    int flag;//用flag去做标记记录相同的字符
    for(i = 0; i < lenA; i++)
    {
        flag = 0;//每次循环都要变为0,防止前面的累加
        for(j = 0; j < lenB; j++)
        {
            if(ch1[i] == ch2[j])
            {
              flag++;//当相同时就加一
            //   printf("%d\n",flag);
            }
        }
        if(flag == 0)//flag为0时意味着没有出现相同,则输出该字符
        {
            printf("%c",ch1[i]);
        }
    }
    return 0;
}

开灯问题:有n盏灯,编号为1-n。第1个人把所有的灯打开,第二个人按下所有编号为2的倍数的开关(这些灯被关掉),第3个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,打开的灯将被关闭),以此类推。一共有k个人,问最后有哪些灯开着?输入:n和k,输出开着的灯的编号。K≤n≤1000.

开灯问题应该是个很经典的问题了吧,我印象中这题我都已经写过两三次了,这题数据不大可以直接用桶排去做,需要注意的是因为第一个人负责开灯所以数组的遍历应该是从第二个人开始的。

#include <stdio.h>

int arr[1010]={0};//数组赋初值
int main()
{
	int n,k;
	scanf("%d %d",&n,&k);
//	int count=0;
	
	for(int i=2;i<=n;i++){
		for(int j=2;j<=k;j++){
			if(i%j==0){
				arr[i]++;//(当i与j相等时或者i是j的倍数时放进桶中)
		    }
		}
	}
		for(int i=1;i<=n;i++){
		if(arr[i]==0||arr[i]%2==0){//当桶里面没东西时则证明没有关灯,需要注意的是当桶中的数是二的倍数时也需要输出,因为关掉后又开了灯
		printf("%d ",i);
		}
	}
	return 0;
}

黑色星期五:13号又是星期五是一个不寻常的日子吗? 13号在星期五比在其他日少吗?为了回答这个问题,写一个程序来计算在n年里13 日落在星期一,星期二......星期日的次数.这个测试从1900年1月1日到 1900+n-1年12月31日.n是一个非负数且不大于400. 这里有一些你要知道的: 1900年1月1日是星期一. 4,6,11和9月有30天.其他月份除了2月有31天.闰年2月有29天,平年2月有28天. 年份可以被4整除的为闰年(1992=4*498 所以 1992年是闰年,但是1990年不是闰年) 以上规则不适合于世纪年.可以被400整除的世纪年为闰年,否则为平年.所以,1700,1800,1900和2100年是平年,而2000年是闰年. 请不要预先算好数据!

黑色星期五在网上也是很常见的一种题目,只要理清年月日之间的关系以及注意闰年的时候二月有二十九天,便可将此题写出,值得注意的是这题逻辑稍微有点复杂,需要用纸币在纸上写出。

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

int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//首先用一个数组去记录每个月的天数,因为数组开端是0所以数组多开了一格初始化为0,这样月份就从一月开始
int week[7]={0};//用一个数组去记录每周内每天出现的次数
int main()
{
	int year=1900;
	int n;
	int count=1;//一月一日是周一
	scanf("%d",&n);
	for(int i=0;i<n;i++,year++){
		if(year%400==0||(year%100!=0&&year%4==0)){
			mon[2]=29;//判断闰年对二月做出改变
		}
		for(int month=1;month<13;month++){//月轮回
			for(int day=1;day<=mon[month];day++){//每日
				if(day==13){
				week[count]++;//每逢十三就加一
		        }
		    count=(count+1)%7;//一周七天轮回
		    }
	    }
	   mon[2]=28;//记得要将二月变回二十八日
    }
        printf("%d ",week[6]);
        for(int i=0;i<=5;i++)
        printf("%d ",week[i]);//注意题目输出要求
    return 0;
}

小明的三角形: 自从小明上了 大学之后,就感觉整个人的智商就不够用了 ,连个简单的判断三角形都不会了。那么作为聪明的你们,是时候展现真正的技术了。

这题就是个简单题,送分的,但是我也不清楚为什么不能用两边和大于第三边做,只能用两边之差小于第三边,注意题目的数据范围(我做了一个排序去保证a<b<c,我不确定题目的样例是否都是满足这个关系)。

#include <stdio.h>

int main()
{
    long int a,b,c;
    scanf("%ld %ld %ld",&a,&b,&c);
    while(a!=0&&b!=0&&c!=0)
    {
        int t;
        if(a>b)
        {
            t = a;
            a = b;
            b = t;
        }
        if(b>c)
        {
            t = b;
            b = c;
            c = t;
        }
        if(a>c)
        {
            t = a;
            a = c;
            c = t;
        }
        if(c-b<a)
        {
            printf("yes\n");
        }else{
            printf("no\n");
        }
        scanf("%ld %ld %ld",&a,&b,&c);
    }
    return 0;
}

数数字:问题很简单有个1到n的数列,数一下其中能够被2,3,5整除的数字的个数。例如当n = 6 ,的时候有 2,3,4,5 , 6.这5个数满足条件,所以我们应该输出5,是不是很简单?

这个题目一看,哎送分题,但是一不注意取值范围和时间限制,就变成了送命题,我开始写了很久都是时间超限,一眼写出的代码如下:

#include <stdio.h>

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int i;
        int count = 0;
        for(i = 1; i <= n; i++)
        {
            if(i % 2 == 0)
            {
                count++;
            }
            else if(i % 3 == 0)
            {
                count++;
            }
            else if(i % 5 == 0)
            {
                count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}

这样的代码很容易超限,所以后来我想办法把重复的数字直接统计就行不需要再做判断这样的话时间就会少很多,但是用筛选法并不好做,于是我在百度上找到了一个叫做容斥原理的东西,这里需要引入容斥原理的概念这题目就很容易写出来,先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。用容斥原理的话时间复杂度也会低不少,很大的数也能一下子就算出答案。

用韦恩图大概就是这样

 红色重叠部分则是需要去除的,剩下的白色部分就是我们要找的集合,于是新的代码就诞生了:

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

int main()
{
    int n;
    int a,b,c;
    int a1,b1,c1;
    int sum;
    while(scanf("%d",&n)!=EOF)
    {
        a = n / 2;
        b = n / 3;
        c = n / 5;
        
        a1 = n / (2*3);
        b1 = n / (2*5);
        c1 = n / (3*5);
        
        sum = n / (2*3*5);
        printf("%d\n",a+b+c-a1-b1-c1+sum);//容斥原理
    }
    return 0;
}

黑黑的小叶子:

 从前有一个小叶子,他很黑,非常黑,但自从来了学校后,由于天天宅,竟按一定比率慢慢变白了。现给出小叶子的黑化程度n和变白比率v,求m天后小叶子的黑化程度。

大水题一个,其实只需要弄清楚变白比率v的关系式就行

#include <stdio.h>

int main()
{
    float n;
    float v,V;
    float m;
    scanf("%f",&n);
    scanf("%f",&m);
    scanf("%f",&v);
    float temp = n;
    for(int i = 0;i < m; i++)
    {
        temp *= v;
        V = n - temp;
        temp = V;
        n = V;
        // printf("%f\n",temp);
    }
    printf("%.1f",V);
    return 0;
}

兔子的谎言:脑静急转弯

。。。。。。。开始我还做错了一次想错了

#include <stdio.h>
 
int main()
{
    printf("甲:2岁\n乙:4岁\n丙:3岁\n丁:1岁\n");
    return 0;
}

接下来就是今天学习的内容:

今天去MOOC上重新复习了一遍字符串(对字符串理解还不是很深),以及指针的使用以及运作。

还有今天学习的《啊哈!算法》,出于对书的严谨我决定从头开始看,但是排序的内容大部分我都会了桶排与冒泡也在其他文章中写过,今天的学习对我影响最深的应该是快速排序,让我加深了对快排的理解(我自己平常很少用到快排)。快排呢听名字就知道它很快,快到什么程度,它的平均时间为O(NlogN),最慢也是与冒泡一致为O(N*N)。

#include <stdio.h>

int a[100];//定义全局变量,该变量要在子函数中使用
void Quicksort(int left,int right)
{
    int i,j,t,temp;
    if(left > right)
    {
        return;
    }
    temp = a[left];//temp存储基准数
    i = left;
    j = right;
    while(i != j)
    {
        //顺序很重要,要先从右往左找
        while(a[j] >= temp && i < j)
        {
            j--;
        }//再从左往右找
        while(a[i] <= temp && i < j)
        {
            i++;
        }
        //交换两个数在数组中的位置
        if(i < j)
        {
            t = a[j];
            a[j] = a[i];
            a[i] = t;
        }//当i与j还没有相遇的时候
    }
    a[left] = a[i];
    a[i] = temp;//基准值归位

    Quicksort(left,i-1);//继续处理左边,这是个递归的过程
    Quicksort(i+1,right);//同上,处理右边,递归
    // return NULL;
}
int main()
{
    int i,j;
    int n;
    scanf("%d",&n);//读取数据
    for(i = 0; i < n; i++)
    scanf("%d",&a[i]);
    Quicksort(0,n-1);//函数调用
    for(i = 0; i < n; i++)
    printf("%d ",a[i]);
    return 0;
}

今天的学习到这里就差不多已经结束了,今天也没学到啥很多有用的内容,明天继续加油吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值