C/C++模拟问题(二)

日期问题

前置问题

  • year——>闰年?
year%400==0||year%100!=0&&year%4==0
&&的优先级高于||
  • month——>有多少天?
    month用int来表示,用一个辅助数组
mday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}

用空间换时间

题目
1.今年的第几天?
描述:输入年月日,计算该天是本年的第几天
输入:包括3个整数:
年(1<=Y<=3000)
月(1<=M<=12)
日(1<=D<=31)
输出:输入可能有多组测试数据,对于每组测试数据,输出一个整数,代表Input中的年、月、日对应本年的第几天

样例:
输入:
1998 9 20
2000 5 1
输出
263
122

方案一:用空间换时间

#include<cstdio>
int main() {
	int year, mon, day;
	int mday[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int totalDay[13] = { 0 };
	for (int mon = 2; mon <= 12; mon++) {
		totalDay[mon] = totalDay[mon - 1] + mday[mon-1];
	}
	while (scanf("%d%d%d", &year, &mon, &day) != EOF) {
		//如果是闰年
		bool isLeap = year % 400 == 0 || year % 100 != 0 && year % 4 == 0;
		if (isLeap == true && mon >= 3) {
			printf("%d\n", totalDay[mon] + day + 1);
		}
		else {
			printf("%d\n", totalDay[mon] + day );
		}
	}
}

方案二:1990 1 1->1990 1 2->…->所求**【万能方案】**

2.打印日期
描述:给出年份m和一年之中的第n天,算出第n天是几月几日
输入:输入包括两个整数y(1<=y<=3000),n(1<=n<=366)
输出:可能有多组测试数据,对于每组数据,按yyyy-mm-dd的格式将输入中对于的日期打印出来
【万能方案】nextDay
如何实现yyyy-mm-dd格式
%4d不足则用空格填充
%04d不足则用0填充

#include<cstdio>
int main() {
	int y, n;
	int mday[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	while (scanf("%d%d", &y, &n) != EOF) {
		int mon = 1;
		int day = 1;
		for (int i = 0; i < n-1; i++) {//注意不是n,而是n-1,因为是从1-1开始判断的
			//闰年问题
			bool isLeap = y % 400 || y % 100 != 0 && y % 4 == 0;
			if (isLeap == true) {
				mday[2] = 29;
			}
			else {
				mday[2] = 28;
			}
			++day;
			if (day > mday[mon]) {
				++mon;
				day = 1;
				if (mon > 12) {
					mon = 1;
					++y;
				}
			}
		}
		printf("%04d-%02d-%02d", y, mon, day);
	}
}

3.day of week
示例

输入: 9 October 2001
      14 October 2001
输出:Tuesday
      Sunday 

C风格的字符串,用于输入输出 char[]
C++风格的字符串,用于复杂操作 string

include<string> 
using namespace std;
//初始化 string str1=str;//"hello"
连接 str1+"world"——>"helloworld"
字符 str1[0]——>'h'
长度 str1.length()
判断相等 str1=="hello"
比较字符 str1>"abandon"
从C++=>C str1.c_str1()

map映射

#include<map>
using namespace std;
//键key-->值value
map<string,string>myMap={
{"Caixukun","ikun"},
{"Wuyifan","meigeni"}
};
char str[100];
scanf("%s",str);
string name=str;
//myMap[key]根据key映射到对应的值(C++风格的字符串)
printf("%s的粉丝被称为%s\n",name.c_str(),myMap[name].c_str());

代码

#include<cstdio>
#include<string>
#include<map>
using namespace std;
int main() {
	int mday[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	string intToWeekday[7] = { "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" };
	map<string, int>monthToint = {
		{"January",1},
		{"Februray",2},
		{"March",3},
		{"April",4},
		{"May",5},
		{"June",6},
		{"July",7},
		{"Auguest",8},
		{"September",9},
		{"October",10},
		{"November",11},
		{"December",12}
	};

	int year,mon, day;
	char str[100];
	string month;
	bool isBefore;
	//9 October 2001
	while (scanf("%d%s%d", &day, str, &year )!= EOF){
		month = str;//把字符串从C风格转换成C++风格
		mon = monthToint[month];//从字符串到整数
		if (year < 2023
			|| 2023 == year && mon < 2
			|| 2023 == year && 2 == mon && day < 6) {
			isBefore = true;
		}
		else {
			isBefore = false;
		}
		//从begin走到end
		int begYear, begMon, begDay, endYear, endMon, endDay;
		if (isBefore) {
			begYear = year;
			begMon = mon;
			begDay = day;
			endYear = 2023;
			endMon = 2;
			endDay = 6;
		}
		else {
			begYear = 2023;
			begMon = 2;
			begDay = 6;
			endYear = year;
			endMon = mon;
			endDay = day;
		}
		int totalDay = 0;
		while (true) {
			if (begYear == endYear && begMon == endMon && begDay == endDay) {
				break;
			}
			++totalDay;
			bool isLeap = begYear % 400 == 0 || begYear % 100 != 0 && begYear % 4 == 0;
			if (isLeap == true) {
				mday[2] = 29;
			}
			else {
				mday[2] = 28;
			}
			++begDay;
			if (begDay > mday[begMon]) {
				begDay = 1;
				++begMon;
				if (begMon > 12) {
					begMon = 1;
					begYear++;
				}
			}
		}
		if (isBefore) {
			//(x+totalDay)%7=4-->(11-totalDay%7)%7
			printf("%s\n", intToWeekday[(11 - totalDay % 7) % 7].c_str());
		}
		else {
			printf("%s\n", intToWeekday[(totalDay + 1) % 7].c_str());//2023-2-6是周一
		}
	}
}

4.剩下的树
描述:有一条长度为整数L(1<=L<=10000)的马路,可以将它想象为数轴上长度为L的一条线段。起点是坐标源点。在每个整数坐标点处有一棵树,在0,1,2,…,L;L+1个位置上有L+1棵树。限制要移走一些树,移走的树的区间用一对数字表示,如“100 200”表示移走从100到200之间(包括端点),可能有M个区间,区间之间可能重叠。现在要求移走所有区间的树之后剩下的树
输入:两个整数L(1<=L<=10000)和M(1<=M<100).接下来有M组整数,每组有一对数字
输出:可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的根数
样例:

输入:
500 3
100 200
150 300
470 471
输出:
298

代码

#include<cstdio>
int main() {
	int tree[10000];//1:表示活着,0:表示死了
	int L, M;
	scanf_s("%d%d", &L, &M);
	//种L+1棵树
	for (int i = 0; i <= L; i++) {
		tree[i] = 1;
	}
	for (int idx = 0; idx < M; idx++) {//外面的循环使用不常见的变量名,避免冲突
		int left, right;
		scanf_s("%d%d", &left, &right);
		for (int i = left; i <= right; i++) {
			tree[i] = 0;
		}
	}
	int totalNumber = 0;
	for (int i = 0; i <= L; i++) {
		if (tree[i] == 1) {
			++totalNumber;
		}
	}
	printf("%d\n", totalNumber);
}

5.手机键盘
描述
按照手机键盘输入字母的方式。计算所花费的时间,例如,a,b,c都在“1”键上,输入a只需按1次键,输入c需要连续按3次键。如果连续两个字符不在一个键上,那么可以直接按; 例如,ad需要按2次,kz需要按6次,那么两次按键之间需要等一段时间:例如ac,按了a之后,需要等一会儿才能按c,现在假设每被按一次需要花费一个时间段,等待时间需要2个时间段。现在输出一串字符,计算输入它所花费的时间。
输入
一个长度不大于100的字符串,串种只有手机键上有的小写字母。
输出
输入可能包含多组数据,对于每组数据,输出按下input所给字符串需要时间。
样例:

输入:
 	 bob
     www
输出:
	  7
      7

九宫格键盘
在这里插入图片描述
题解思路

  • 字符串种每个字符本身要按几下——>map<char,int>
  • 每个字符属于哪个按键——>判断是否等待【使用map<char,int>】

代码

#include<map>
#include<cstdio>
using namespace std;
int main() {
	//某个字母需要输出多长时间
	map<char, int>inputTime = {
		{'a',1},{'b',2},{'c',3},
		{'d',1},{'e',2},{'f',3},
		{'g',1},{'h',2},{'i',3},
		{'j',1},{'k',2},{'l',3},
		{'m',1},{'n',2},{'o',3},
		{'p',1},{'q',2},{'r',3},{'s',4},
		{'t',1},{'u',2},{'v',3},
		{'w',1},{'x',2},{'y',3},{'z',4}
	};
	//某个字母属于哪个按键
	map<char, int>keyMap = {
		{'a',2},{'b',2},{'c',2},
		{'d',3},{'e',3},{'f',3},
		{'g',4},{'h',4},{'i',4},
		{'j',5},{'k',5},{'l',5},
		{'m',6},{'n',6},{'o',6},
		{'p',7},{'q',7},{'r',7},{'s',7},
		{'t',8},{'u',8},{'v',8},
		{'w',9},{'x',9},{'y',9},{'z',9}
	};
	char str[101];
	while (scanf_s("%s", str, sizeof(str)) != EOF) {
	//用scanf则是:scanf("%s",str);
		int lastInput = 1;//初始的时候,lastInput置为和其他所有按键都不同的键
		int totalTime = 0;
		for (int i = 0; str[i] != '\0'; ++i) {
			//遍历C风格的字符串
			//判断一下是否需要等待
			if (lastInput == keyMap[str[i]]) {
				totalTime += 2;//等待
			}
			totalTime += inputTime[str[i]];//输入本字符需要的时间
			lastInput = keyMap[str[i]];//记录本次按下的数字
		}
		printf("%d\n", totalTime);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值