顺子日期
#include<iostream>
using namespace std;
typedef long long ll;
bool judge(ll n)
{
int arr[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int month = n % 10000 / 100;
int day = n % 100;
if(day <= arr[month] && day > 0)
return true;
return false;
}
int main()
{
int sum = 0;
for(ll i = 20220101; i <= 20221231; i++)
{
int a, b, c, d;
if(judge(i))
{
a = i % 10000 / 1000;
b = i % 1000 / 100;
c = i % 100 / 10;
d = i % 10;
if(b - a == 1 && c - b == 1 || c - b == 1 && d - c == 1)sum ++;
}
}
cout << sum << endl;
return 0;
}
货物摆放
#include<iostream>
#include<cmath>
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;
ll arr[N], cnt;
ll n = 2021041820210418;
int main()
{
for(int i = 1; i <= sqrt(n); i++){//求出因子
if(n % i == 0){
arr[++cnt] = i;
if(i * i != n)arr[++cnt] = n / i;//如果i是n的因子的话,n / i 不等于n的话也是n的因子
}
}
ll res = 0;
//枚举
for(int i = 1; i <= cnt; i++)
for(int j = 1; j <= cnt; j++)
for(int k = 1; k <= cnt; k++)
if(arr[i] * arr[j] * arr[k] == n) res++;
cout << res << endl;
return 0;
}
数的分解
#include<iostream>
using namespace std;
//判断当前正数是否包含2和4
bool check(int x)
{
while(x)
{
int a = x % 10;
if(a == 2 || a == 4)
return false;
x /= 10;
}
return true;
}
int main()
{
int cnt = 0;
for(int i = 1; i < 2019; i++)
{
int j = i + 1;
//枚举当前i,j
while(true) {
int k = 2019 - i - j;
//如果k小于等于j说明这个数之前就枚举到了就要退出循环
if(k <= j)break;
if(check(i) && check(j) && check(k))
cnt++;
//当前j自增
j++;
}
}
cout << cnt << endl;
return 0;
}
蓝桥杯–赢球票
某机构举办球票大奖赛。获奖选手有机会赢得若干张球票。
主持人拿出 N 张卡片(上面写着 1~N 的数字),打乱顺序,排成一个圆圈。你可以从任意一张
卡片开始顺时针数数: 1,2,3..... 如果数到的数字刚好和卡片上的数字相同,则把该卡片收入囊
中,从下一个卡片重新数数。 直到再无法收获任何卡片,游戏结束。囊中卡片数字的和就是赢得
球票的张数。
比如:
卡片排列是:1 2 3
我们从1号卡开始数,就把1号卡拿走。再从2号卡开始,但数的数字无法与卡片对上,很快数字
越来越大,不可能再拿走卡片了。因此这次我们只赢得了1张球票。还不算太坏!如果我们开始就
傻傻地从2或3号卡片数起,那就一张卡片都拿不到了。
如果运气好,卡片排列是 2 1 3
那我们可以顺利拿到所有的卡片!
本题的目标就是:已知顺时针卡片序列。
随便你从哪里开始数,求最多能赢多少张球票(就是收入囊中的卡片数字之和)
输入格式
第一行一个整数N(N<100),表示卡片数目
第二行 N 个整数,表示顺时针排列的卡片
输出格式
一行,一个整数,表示最好情况下能赢得多少张球票
用户输入:
3
1 2 3
程序应该输出:
1
用户输入:
3
2 1 3
程序应该输出:
6
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e2 + 10;
//开两个数组,当枚举完一个数的位置的时候重新赋值
int n, a[N], backup[N];
int get(int k)
{
int sum = 0, cnt = 1;
//用for循环一个赋值也可以
memcpy(a, backup, sizeof a);
while(true)
{
//当前彩票被拿过的话就走下一个,%n的原因是到最后一张彩票的时候回头
while(a[k] == 0)
k = (k + 1) % n;
//如果当前位置等于彩票数的话就拿下来并标记被拿过 ,当前位置也要重新赋值
if(a[k] == cnt)
{
sum += a[k];
a[k] = 0;
cnt = 1;
//否则就看下一张
}else {
cnt++;
}
//彩票位置++
k = (k + 1) % n;
//如果当前彩票数组最大值为0的话说明所有的彩票都拿到了直接返回sum
if (*max_element(a, a + n) == 0)
return sum;
//如果cnt已经大于n张彩票了说明当前sum已经是最优解了
if(cnt > n)
return sum;
}
return -1;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> backup[i];
int res = 0;
for (int i = 0; i < n; i++)
res = max(res, get(i));
cout << res << endl;
return 0;
}
蓝桥杯–猴子分香蕉
5只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。
第1只猴子醒来,把香蕉均分成5堆,还剩下1个,就吃掉并把自己的一份藏起来继续睡觉。
第2只猴子醒来,重新把香蕉均分成5堆,还剩下2个,就吃掉并把自己的一份藏起来继续睡觉。
第3只猴子醒来,重新把香蕉均分成5堆,还剩下3个,就吃掉并把自己的一份藏起来继续睡觉。
第4只猴子醒来,重新把香蕉均分成5堆,还剩下4个,就吃掉并把自己的一份藏起来继续睡觉。
第5只猴子醒来,重新把香蕉均分成5堆,哈哈,正好不剩!
请计算一开始最少有多少个香蕉。
分析思路:
枚举法、筛选
至少要从5开始枚举筛选
除以5,余1,吃掉1,藏1份,剩四份
除以5,余2,吃掉1,藏1份,剩四份
除以5,余3,吃掉1,藏1份,剩四份
除以5,余4,吃掉1,藏1份,剩四份
恰好被5整除
#include<iostream>
using namespace std;
bool check(int k)
{
for(int i = 1;i <= 4; i++){
//分成五堆不能为每一堆0判断一下
if(k && k % 5 != i)
return false;
k -= i;
k = k / 5 * 4;
}
if(k && k % 5 == 0)
return true;
return false;
}
int main()
{
int i = 1;
while(true){
if(check(i)){
cout << i << endl;
break;
}
i++;
}
return 0;
}
回文日期
2020
年春节期间,有一个特殊的日期引起了大家的注意:2020
年 2
月 2
日。
因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8
位数是 20200202,恰好是一个回文数。
我们称这样的日期是回文日期。
有人表示 20200202 是“千年一遇” 的特殊日子。
对此小明很不认同,因为不到 2
年之后就是下一个回文日期:20211202 即 2021
年 12
月 2
日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。
对此小明也不认同,因为大约 100
年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121
年 12
月 12
日。
算不上“千年一遇”,顶多算“千年两遇”。
给定一个 8
位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
注意
下一个回文日期和下一个 ABABBABA 型的回文日期可能是同一天。
ABABBABA 型的回文日期,需要满足 A≠B
。
输入格式
输入包含一个八位整数 N
,表示日期。
输出格式
输出两行,每行 1
个八位数。
第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
数据范围
对于所有评测用例,10000101≤N≤89991231
,保证 N
是一个合法日期的 8
位数表示。
输入样例:
20200202
输出样例:
20211202
21211212
#include<iostream>
using namespace std;
typedef long long ll;
int arr[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30 ,31, 30, 31};
//判断闰年
bool is_run(int year)
{
if(year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
return true;
return false;
}
//判断日期
bool checktime(int md)
{
int m = md / 100;
int d = md % 100;
if(m > 0 && m <= 12 && d >= 1 && d <= arr[m])
return true;
return false;
}
int main()
{
ll year;
cin >> year;
ll sum = 0;
for(ll i = year + 1;; i++){
//判断当前年份是闰年还是平年
if(is_run(i / 10000)){
arr[2] = 29;
} else {
arr[2] = 28;
}
ll temp = i;
sum = 0;
while(temp){
sum = sum * 10 + temp % 10;
temp /= 10;
}
//如果回文并且日期合法输出
if(i == sum && checktime(i % 10000)) {
cout << i << endl;
break;
}
}
//20200202
for(ll i = year + 1;; i++){
int a = i / 10000000;
int b = i / 1000000 % 10;
int c = i / 100000 % 10;
int d = i / 10000 % 10;
int e = i / 1000 % 10;
int f = i / 100 % 10;
int g = i / 10 % 10;
int h = i % 10;
//保证a c f h 都是相等的;保证 b d e g 都是相等的。为了保证八个数字不都一样所以加个 a != b判定
if(a == c && c == f && f == h && b == d && d == e && e == g && a != b && checktime(i % 10000)){
cout << i << endl;
break;
}
}
return 0;
}