最近在刷题过程中了解了scanf的更深层的功能。
有关scanf的用法
scanf有两种用法:
- scanf(“输入控制符”,输入参数);
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
printf("%d\n",a);
}
这个在我们做题过程中经常会遇到,根据要求输入数据,但是我们要清楚的是输入的123一开始是字符,按照我们的要求转换成了整型123。
2. scanf(“输入控制符 非输入控制符”,输入参数);
# include<stdio.h>
int main()
{
int a;
scanf("a=%d",&a);
printf("a=%d",a);
return 0;
}
在你输入过程中必须连带a=等非输入控制符一起输入才行,如果你只输入了15,那么会输入以下内容:
这是为什么呢?因为scanf没有正确的读入a=15,所以就不存在输出a=15,在此要说明下用dev编译器定义了整型a并没有初始化,所以输出了0,在其他编译器上可能会输出其他值(比赛过程中初始化也很重要)
这里只是简单介绍了scanf的两种格式,更详细可以自行百度,接下里重点介绍第二种方法:请看题
题目描述
有一些日期,日期格式为“MM/DD/YYYY”。编程将其按日期大小排列。
输入
无
输出
无
样例输入
15/12/1999
10/21/2003
10/22/2003
02/12/2004
11/30/2005
12/31/2005
样例输出
15/12/1999
10/21/2003
10/22/2003
02/12/2004
11/30/2005
12/31/2005
解题思路:你们是怎么输入的呢?其中包含了/而且还要对日期进行排序,我们首先要把日期分离成年月日,这里其实用scanf就可以实现(sscanf也可以实现,这里不做过多的介绍),然后对日期排个序,这里要用到c++中的sort排序。然后就大功告成了。
code:
# include<iostream>
# include<cstdio>
# include<algorithm>
using namespace std;
struct data{
int year;
int month;
int day;
}data1[1000];
bool cmp(struct data a,struct data b)
{
if(a.year==b.year)
{
if(a.month==b.month)
{
return a.day<b.day;
}
else
return a.month<b.month;
}
else
return a.year<b.year;
}
int main()
{
int i=0;
while(scanf("%d/%d/%d",&data1[i].month,&data1[i].day,&data1[i].year)!=EOF)
i++;
//printf("%d",i);
sort(data1,data1+i,cmp);
for(int j=0;j<i;j++)
printf("%02d/%02d/%d\n",data1[j].month,data1[j].day,data1[j].year);
return 0;
}
这里就用到了第二种格式,scanf("%d/%d/%d",&a,&b,&c);直接分离出了,年月日。(有兴趣可以做一下此题)题的地址
问题 1883: [蓝桥杯][2017年第八届真题]日期问题
题目描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输出
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入
02/03/04
样例输出
2002-03-04
2004-02-03
2004-03-02
解题思路:这道题是2017年第八届蓝桥杯省赛c/c++B组的一道题,没有特别的考算法,考的就是细节问题,这里也用到了scanf的第二种格式。
- 三个数字分别代表年月日或日月年或月日年
- 年月日要分别有效,何为有效?年数在00到99之间(只需判断是否是在20世纪还是在21世纪)月份在1到12范围内,天数在对应月的范围内有效即可(闰年2月份多一天)
- 年月日可能会重复另加判断重复去掉即可例如02/02/04存在两个2004-02-02 出现的时间从小到大排序即可
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int ans=0;
struct Data
{
int year;
int month;
int day;
}data[3];
int month[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int is_leap_year(int year)
{
if(year%400==0||year%4==0&&year%100!=0)
return 1;
else
return 0;
}
bool cmp(struct Data a,struct Data b)
{
if(a.year==b.year)
{
if(a.month==b.month)
{
return a.day<b.day;
}
else
return a.month<b.month;
}
else
return a.year<b.year;
}
int Judge(int year,int month,int day,int ans)
{
for(int i=0;i<ans;i++)
if(year=data[i].year&&month==data[i].month&&day==data[i].day)
return 0;
return 1;
}
int fun(int y,int m,int d)
{
int ty=y,tm=m,td=d;
if(y>=60)
ty+=1900;
else
ty+=2000;
if(tm>=1&&tm<=12)
{
int temp=month[tm-1];
if(is_leap_year(y)&&tm==2)
temp++;
if(td>=1&&td<=temp&&Judge(ty,tm,td,ans))
{
data[ans].year=ty;
data[ans].month=tm;
data[ans].day=td;
ans++;
}
}
}
int main()
{
int a,b,c;
scanf("%d/%d/%d",&a,&b,&c);
fun(a,b,c);
fun(c,a,b);
fun(c,b,a);
sort(data,data+ans,cmp);
for(int i=0;i<ans;i++)
printf("%02d-%02d-%02d\n",data[i].year,data[i].month,data[i].day);
//printf("%02d-%02d-%02d",a,b,c);
return 0;
}
后序继续了解到scanf的用法回来再更新。