【反思与总结---7】在线OJ⑦

美国节日、分解因数

题目要求:

输入一个年份,输出这一年所有美国节日

解题思路:

<1>.蔡勒公式
<2>.这种题很烦,格式的要求,而且以前根本不知道这个公式

代码示例:

#include<iostream>
#include<cstdio>
#include <iomanip>

using namespace std;

int dayofWeek(int year, int month, int day)
{
	//公式要求这样处理
	if (month == 1 || month == 2)
	{
		month += 12;
		year -= 1;
	}

	int century = year / 100;
	year %= 100;

	int week = year + (year / 4) + (century / 4) - 2 * century + 26 * (month + 1) / 10 + day - 1;

	week = (week % 7 + 7) % 7;

	if (week == 0)
	{
		week = 7;
	}

	return week;
}

int dayofDemand(int year, int month, int count, int day_week)
{
	int week = dayofWeek(year, month, 1);

	int day = 1 + (count - 1) * 7 + (7 + day_week - week) % 7;

	return day;
}

void NewYearsDay(int year)
{
	cout << year << "-" << "01" << "-" << "01" << endl;
}

void MartinKingDay(int year)
{
	cout << year << "-" << "01" << "-" << setw(2) << setfill('0') << dayofDemand(year, 1, 3, 1) << endl;
}

void PresidentDay(int year)
{
	cout << year << "-" << "02" << "-" << setw(2) << setfill('0') << dayofDemand(year, 2, 3, 1) << endl;
}

void DeadDay(int year)
{
	//五月的最后一个星期一,从6月第一个往前减
	int week = dayofWeek(year, 6, 1);

	int day = 31 - ((week == 1) ? 6 : (week - 2));

	cout << year << "-" << "05" << "-" << setw(2) << setfill('0') << day << endl;
}

void IndependDay(int year)
{
	cout << year << "-" << "07" << "-" << "04" << endl;
}

void MayDay(int year)
{
	cout << year << "-" << "09" << "-" << setw(2) << setfill('0') << dayofDemand(year, 9, 1, 1) << endl;
}

void ThanksGivingDay(int year)
{
	cout << year << "-" << "11" << "-" << setw(2) << setfill('0') << dayofDemand(year, 11, 4, 4) << endl;
}

void ChrismasDay(int year)
{
	cout << year << "-" << "12" << "-" << "25" << endl;
}

void PrintHliday(int year)
{
	NewYearsDay(year);
	MartinKingDay(year);
	PresidentDay(year);
	DeadDay(year);
	IndependDay(year);
	MayDay(year);
	ThanksGivingDay(year);
	ChrismasDay(year);
}

int main()
{
	int year;

	while (cin >> year)
	{
		PrintHliday(year);
		cout << endl;
	}


	return 0;
}

题目要求:

<1>.输出一个整数
<2>.输出其质数因数的乘积,10=2*5

解题思路:

<1>.从2开始,遍历到sqrt(n)
<2>.n%i== 0,说明这个数是因数,n /=i
<3>.如果n!=i,继续遍历,n==i说明所有因数查找结束

代码示例:

#include<iostream>
#include<math.h>

using namespace std;

int main()
{
	int n;

	while (cin >> n)
	{
		//10--->2*5
		cout << n << " " << "=" << " ";

		int i;

		for (i= 2; i <= sqrt(n); ++i)
		{
			while (n != i)
			{
				if (n%i == 0)
				{
					cout << i << " " << "*" << " ";
					n /= i;
				}
				else
				{
					break;
				}
			}
		}
		cout << n << endl;
	}

	system("pause");
	return 0;
}

淘宝网店、斐波那契凤尾

题目要求:

<1>.月份为素数,一天赚一块钱,月份不是素数,一天赚两块钱
<2>.输入两组年月日,输出赚的钱的数量

解题思路:

<1>.突然一看,2000.1.1-2001.12.31很像一年??其实是两年!!
<2>.所以我一直都少了580天

代码示例:

#include<iostream>
#include<vector>
#include<math.h>

using namespace std;

bool isMonth(int month)
{
	if (month == 1)
	{
		return false;
	}
	for (int i = 2; i <= sqrt(month); ++i)
	{
		if (month%i == 0)
		{
			return false;
		}
	}
	return true;
}

bool isYear(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
	{
		return true;
	}
	return false;
}

int GetYearDay(int year)
{
	if(isYear(year)==true)
	{
		return 2 * 31
			+ 1 * 29
			+ 1 * 31
			+ 2 * 30
			+ 1 * 31
			+ 2 * 30
			+ 1 * 31
			+ 2 * 31
			+ 2 * 30
			+ 2 * 31
			+ 1 * 30
			+ 2 * 31;
	}
	else
	{
		return 2 * 31
			+ 1 * 28
			+ 1 * 31
			+ 2 * 30
			+ 1 * 31
			+ 2 * 30
			+ 1 * 31
			+ 2 * 31
			+ 2 * 30
			+ 2 * 31
			+ 1 * 30
			+ 2 * 31;
	}
}

int GetMoney(int year1, int month1, int day1, int year2, int month2, int day2)
{
	vector<int> days{ 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	if (isYear(year1) == true || isYear(year2) == true)
	{
		days[2] = 29;
	}

	int Money = 0;

	if (year1 == year2)
	{
		if (month1 == month2)
		{
			if (isMonth(month1) == true)
			{
				if (day1 == day2)
				{
					return 1;
				}
				return day2 - day1 + 1;
			}
			else
			{
				if (day1 == day2)
				{
					return 2;
				}
				return 2 * (day2 - day1 + 1);
			}
		}
		//年份相同,月份不同
		else
		{
			int Day = 0;

			for (int i = month1 + 1; i < month2; ++i)
			{
				if (isMonth(i) == true)
				{
					Money += days[i];
				}
				else
				{
					Money += 2 * days[i];
				}
			}
			if (isMonth(month1) == true)
			{
				Money += day1;
			}
			else
			{
				Money += 2 * day1;
			}
			if (isMonth(month2) == true)
			{
				Money += day2;
			}
			else
			{
				Money += 2 * day2;
			}
		}
		return Money;
	}
	//年份不同(暂时没写)
	else
	{
		//2000.1.1   2999.12.31
		//2001-2998 天数 
		int Day = 0;

		Day += GetYearDay(year1);

		for (int i = year1 + 1; i < year2; ++i)
		{
			Day += GetYearDay(i);
		}

		//if (isMonth(month1)==true)
		//{
		//	Day += day1;
		//}
		//else
		//{
		//	Day += 2 * day1;
		//}

		while (month1--)
		{
			switch (month1)
			{
			case 1:
			case 8:
			case 10:
			case 12:
				Day += 62;
				break;
			case 3:
			case 5:
			case 7:
				Day += 31;
				break;
			case 4:
			case 6:
			case 9:
				Day += 60;
				break;
			case 11:
				Day += 30;
				break;
			case 2:
				if (isYear(year1) == true)
				{
					Day += 29;
				}
				else
				{
					Day += 28;
				}
				break;
			default:;
			}
		}

		if (isMonth(month2)==true)
		{
			Day += day2;
		}
		else
		{
			Day += 2 * day2;
		}

		while (month2--)
		{
			switch (month2)
			{
			case 1:
			case 8:
			case 10:
			case 12:
				Day += 62;
				break;
			case 3:
			case 5:
			case 7:
				Day += 31;
				break;
			case 4:
			case 6:
			case 9:
				Day += 60;
				break;
			case 11:
				Day += 30;
				break;
			case 2:
				if (isYear(year2) == true)
				{
					Day += 29;
				}
				else
				{
					Day += 28;
				}
				break;
			default:;
			}
		}
		return Day;
	}
}

int main()
{
	int year1;
	int month1;
	int day1;

	int year2;
	int month2;
	int day2;

	while (cin >> year1 >> month1 >> day1 >> year2 >> month2 >> day2)
	{
		cout << GetMoney(year1, month1, day1, year2, month2, day2) << endl;
	}

	system("pause");
	return 0;
}

题目要求:

<1>.我们随便出一个数n,说出第n个斐波那契数
<2>.当然,斐波那契数会很大,因此,如果第n个斐波那契数不到6位,则说出该数;否则只说出最后6位

解题思路:

先找斐波那契数,判断到没到6位,反正我是对牛客网出题的人很没有好感,因为我每次都按我的理解结果跟他要求的不一样

代码示例:

#include<stdio.h>
#include<iostream>
#include <iomanip>

using namespace std;

int main()
{
	int v[100001];
	int n = 0;
	v[0] = 1;
	v[1] = 1;

	for (int i = 2; i <= 100000; i++)
	{
		v[i] = v[i - 1] + v[i - 2];
		v[i] = v[i] % 1000000;
	}

	while (cin >> n)
	{
		if (n < 29)
		{
			cout << v[n] << endl;
		}
		else
		{
			cout << setfill('0') << setw(6) << v[n] << endl;
		}
	}
	return 0;
}

剪花布条、客似云来

题目要求:

<1>.每组数据包含两个字符串s,t,分别是成对出现的花布条和小饰条
<2>.对应每组输入,输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就输出0,每个结果占一行

解题思路:

<1>.使用STL中的string类的find方法,在s中查找t
<2>.查到之后跳过t的长度之后,继续查,直到没有为止,输出计数count

代码示例:

#include<iostream>
#include<algorithm>
#include<string>

using namespace std;

int main()
{
	string A;
	string B;

	while (cin>>A>>B)
	{
		size_t pos = 0;

		int count = 0;

		while ((pos = A.find(B, pos)) != string::npos)
		{
			count++;
			pos += B.size();
		}

		cout << count << endl;
	}

	return 0;
}

题目要求:

<1>.客人从最初一个人发展成浩浩荡荡成百上千人:1、1、2、3、5……
<2>.每组数据包含两个整数from和to(1≤from≤to≤80),分别代表开店的第from天和第to天
<3>.输出需要做的早餐数,一人只吃一份

解题思路:

<1>.斐波那契的应用
<2>.遍历求和

代码示例:

#include<iostream>

using namespace std;

void Fib(long long num[])
{
	for (int i = 2; i < 83; ++i)
	{
		num[i] = num[i - 1] + num[i - 2];
	}
}

long long Func(long long num[], int from, int to)
{
	long long result = 0;

	for (int i = from - 1; i < to; ++i)
	{
		result += num[i];
	}
	return result;
}

int main()
{
	long long num[83];

	num[0] = 1;
	num[1] = 1;

	Fib(num);

	int from, to;

	while (cin >> from >> to)
	{
		cout << Func(num, from, to) << endl;
	}

	return 0;
}

收件人列表、养兔子

题目要求:

<1>.每组数据的第一行是一个整数n (1≤n≤128),表示后面有n个姓名
<2>.紧接着n行,每一行包含一个收件人的姓名。姓名长度不超过16个字符

解题思路:

<1>.每个名字单独处理,如果有逗号或空格,名字前后都要加双引号
<2>.如果是最后一个名字结束就加换行,不是就加逗号和空格

代码示例:

#include <iostream>
#include <string>
#include <cstdio>

using namespace std;

int main()
{
	int n;

	while (cin >> n)
	{
		cin.get();

		string name;

		for (int i = 0; i < n; i++)
		{
			bool quote = false;

			getline(cin, name);

			if (name.find(',') != string::npos ||
				name.find(' ') != string::npos) 
			{
				quote = true;
			}

			if (quote)
			{
				putchar('\"');
			}

			std::cout << name;

			//名字开始前加一个双引号,结束也要加一个
			if (quote)
			{
				putchar('\"');
			}

			if (i == n - 1) 
			{
				putchar('\n');
			}
			else
			{
				putchar(',');
				putchar(' ');
			}
		}
	}
	return 0;
}

题目要求:

<1>.输入一个数字
<2>.对应输出第n天有几只兔子(假设没有兔子死亡现象)

解题思路:

<1>.看到兔子数量就想到斐波那契的应用
<2>.不需要考虑long long还是高精度,内存够大,python可以表示出任意的数

代码示例:

a=[1,2]
for i in range(2,90):
    a.append(a[-1]+a[-2])

while True:
    try:
        num=int(input())
        print (a[num-1])
    except:
        break

年会问题、抄送人列表

题目要求:

<1>.每个人写下自己的名字放进箱子,抽到自己名字就是中奖
<2>.求出无人中奖的概率

解题思路:

<1>.D(n) = (n-1) [D(n-2) + D(n-1)],特殊地,D(1) = 0, D(2) = 1
<2>.第N项错排的方法数/N的阶乘
<3>.1/2转为50.00%,先要把1/2转为50,分子*100

代码示例:

#include<iostream>
#include<cstdio>

using namespace std;

int main()
{
	long long D[]={0,1,2};
	long long F[]={0,1,2};

	for(int i=3;i<22;++i)
	{
		D[i]=(i-1)*(D[n-1]*D[n-2]);
		F[i]=i*F[i-1];
	}

	int n;

	while(cin>>n)
	{
		printf("%.2ff%%\n",D[n]/F[n]);
	}

	return 0;
}

题目要求:

<1>.第一行抄送列表,姓名之间用一个逗号隔开,如果姓名中包含空格或逗号,则姓名包含在双引号里
<2>.第二行只包含一个姓名,是待查找的用户的名字
<3>.如果第二行的名字出现在收件人列表中,则输出“Ignore”输出“Important!”

解题思路:

<1>.把名字都存到Res里,最后把待查找的名字拿出来和Res里的比
<2>.如果找到了就输出"Ignore",没找到就输出"Important!"
<3>.双引号和下个双引号之间的是名字,截下来保存
<4>.不是引号说明直接是名字,找到下一个逗号,把之前的保存下来,没找到就说明是一个完整的名字,直接保存

代码示例:

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

int main()
{
	string line;

	while (getline(cin, line))
	{
		vector<string> Res;

		size_t pos = 0;

		while (pos < line.length())
		{
			if (line[pos] == '\"')
			{
				size_t end = line.find("\"", pos + 1);

				Res.push_back(line.substr(pos + 1, end - pos - 1));//end-(pos+1)

				pos = end + 2;
			}
			else
			{
				size_t end = line.find(",", pos + 1);

				if (end == string::npos) 
				{
					Res.push_back(line.substr(pos, line.size() - pos));
					break;
				}

				Res.push_back(line.substr(pos, end - pos));

				pos = end + 1; 
			}
		}

		//获取第二行的内容
		getline(cin, line);

		if (Res.end() == find(Res.begin(), Res.end(), line))
		{
			cout<<"Important!"<<endl;
		}
		else
		{
			cout<<"Ignore"<<endl;
		}
	}

	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值