美国节日、分解因数
题目要求:
输入一个年份,输出这一年所有美国节日
解题思路:
<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;
}