C语言学习笔记(七)---一些刷题记录

来源:互联网 发布:淘宝处罚考试在哪里 编辑:程序博客网 时间:2024/06/05 07:32

最近在学校的oj上做了一些题目,都不是很难,今天本想统一写一下题解但时间太晚,篇幅太长,于是先写三道比较基础的。这两天被一道题卡了好久,最后在dalao的指导下改了输入方式就过了。我们讨论了好久也没弄清楚到底是哪出了问题,有点难过,想早点休息。
学校的oj外网最近好像一直上不了,于是就先不贴链接了。
286是一道关于字符串处理的分支结构练习题(一道阅读题)。
517是一道关于数组的分支和循环结构练习题。
288是一道典型素数判断题,相关的算法很有意思,我打算单独写一篇文章来简单介绍一下这些算法。

286. 密码注册规则

时间限制 1000 ms 内存限制 65536 KB
题目描述
为保护交易安全,某宝在会员注册时,对密码有严格的要求。 密码必须符合以下特征: 1.密码的长度大于等于8。 2.密码中的字符应该来自下面4组“字符类别”中的至少3组: ①大写字母:ABCD…XYZ ②小写字母:abcd…xyz ③数字:1234567890 ④特殊符号:~!@#$%^&*()-=。 请判别输入的密码是否符合规则。

输入格式
每行的输入数据是一串密码,密码长度 不会超过50,且不会包含以上 4 种之外的字符类别。 若输入“END”则结束程序

输出格式
符合规则的输出”YES”,否则输出“NO”

输入样例
123456
20130410BUPT
20130410Bupt
GRL@1112
END

输出样例
NO
NO
YES
YES

//  286. 密码注册规则////  Created by passer_by_a on 10/25/17.//  Copyright © 2017 passer_by_a. All rights reserved.//#include <stdio.h>int main() {    char a[52]={0};    int i,t;    while(1)    {        t=0;        int c[5]={0};//        for(i=1;;i++)        {            scanf("%c",&a[i]);            if(a[i]=='\n') break;            if(a[i]>='a'&&a[i]<='z') c[1]=1;            else if(a[i]>='0'&&a[i]<='9') c[2]=1;            else if(a[i]>='A'&&a[i]<='Z') c[3]=1;            else c[4]=1;        }        if(a[1]=='E'&&a[2]=='N'&&a[3]=='D') break;        for(int j=1;j<=4;j++)        {            t+=c[j];        }        if(t<=2||i<=7) printf("NO\n");//判断是否合法        else printf("YES\n");    }    return 0;}

运行时间: 2 ms 使用内存: 11024 KB
这道题其实很简单,我的思路是一个一个接收字符并判断属于哪种字符,并记录某种字符是否出现过。一开始我没看清楚题意,还特意定义了一个字符数组来存放那些特殊字符,一个一个比对,很麻烦。但其实题意里有写只有这四种字符所以只要不是那三种就可以了。

517. 今年的第几天

题目描述
输入年、月、日,计算该天是本年的第几天。
友情提示,平年和闰年的区别:
公元年数可被4整除为闰年,但是正百的年数必须是可以被400整除的才是闰年.其他都是平年.闰年的2月有29天,而平年二月有28天.例如:1996年是闰年,2000年是闰年,1900年是平年,1997年是平年.

输入格式
包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。

输出格式
输出一个整数,代表Input中的年、月、日对应本年的第几天。

输入样例
1990 9 20
输出样例
263

//  517. 今年的第几天////  Created by passer_by_a on 10/19/17.//  Copyright © 2017 passer_by_a. All rights reserved.//#include<stdio.h>int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};int monr[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};int main(){    int n,x,y,z;    int i,j;    int ans;        ans=0;        scanf("%d %d %d",&x,&y,&z);        if((x%4==0&&x%100!=0)||x%400==0)//判断闰年            for(j=1;j<y;j++){                ans+=monr[j];            }        else for(j=1;j<y;j++){            ans+=mon[j];        }        ans+=z;        printf("%d",ans);    return 0;}

运行时间: 6 ms 使用内存: 11048 KB
这道题是道简单的循环和分支结构练习题,只要加上之前每个月的天数和这个月过去的天数就行了。如果题目里不提醒闰年判断的话,可能正确率会下降很多。

288. 素数验证码

题目描述
密码泄露的漏洞终于补上了。但是为了避免恶意猜测密码,某网站推出了素数验证码(好弱的验证码……)。用户需要判定网站给出的数字是否是素数。

输入格式
一个数字,小于1000

输出格式
是素数则输出”YES“,否则输出”NO“

输入样例
19

输出样例
YES

#include <stdio.h>int ss(int t);int main(){    int t;    scanf("%d",&t);    if(ss(t)) printf("YES");    else printf("NO");    return 0;}int ss(int t)//素数判定{    if(t==1||t==2||t==3) return 1;    if(t%2==0) return 0;    for(int i=3;i*i<=t;i++)    {        if(t%i==0) return 0;    }    return 1;}

关于这道题,班里dalao说打表(先算出1-1000的所有素数,然后判断输入地是不是素数)是最优方法。的确,在很多情况下,打表的确很节省时间。但我总觉得这道题里打表不太合适,原因是这道题里每次都是一次性的查询,每次只查一个数,打的表第二次就不能再用了,这样一来,就会有很多冗余的计算和数据。
关于素数的判定,我所知道的最简单的算法就是上课时老师讲的那种朴素算法:判断2—n-1中有没有n的因子。还有一种耗时稍微少一点的算法,也就是我使用的算法:判断2—sqrt(n)中有没有n的因子(因为若n=a*b,那么a、b中有且至少有一个,它的平方小于等于n)。还有几种很有意思的基于概率的算法,后面再讲,这里就不作详述。

原创粉丝点击