蓝桥杯 C++项目题库6

3.6***第十一届蓝桥青少组省赛 C++高级组(20 年 3 月)
选择题:
1.结构化程序所要求的基本结构不包括( B )。
A、顺序结构
B、GOTO()跳转
C、选择(分支)结构
D、重复(循环结构)
2.若定义 int a=2,b=2,下列表达式中值不为 4 的是( A )
A.a*(++b)
B.a*(b++)
C.a+b
D.a*b
3. 在下列选项中,不能输出 100 个整数的是( D )。
4.下列叙述中正确的是( B )。
A. 线性表的链式存储结构与顺序存储结构所需要的存储空间是相同的
B. 线性表的链式存储结构所需要的存储空间一般要多于顺序存储结构
C. 线性表的链式存储结构所需要的存储空间一般要少于顺序存储结构
D. 上述三种说法都不对
5. 小蓝打羽毛球实行积分赛制,获胜积 5 分,打平积 2 分,失败扣 1 分。已知小蓝
在 20 场积分赛后积 61 分且有 3 场比赛打平,那么小蓝的胜率为:( C ) A. 48%
B. 55%
C. 60%
D. 75%
// 3 平 12 胜 5 负
第 122 页 共 256 页
3.6.1 属相
我们中国人对老鼠的感情可不一般,鼠是中国传统十二生肖之首。那么 2020 年
出生的“20 后”是否都是“鼠宝宝”呢?其实不是,2020 年 1 月 1 日~1 月 24 日出
生的“20 后”,仍然是“猪宝宝”,因为他们出生在农历己亥猪年;大年初一(1 月 25
日)及之后出生的“20 后”才是“鼠宝宝”。那么接下来请你判断一下,以下生日的宝
宝是“猪宝宝” 还是“鼠宝宝”?
输入:符合常识的两个空格分隔的整数 month,day,分别代表宝宝出生的月份及
日子,(1<=month<=12, 1<=day<=31)。
输出:若是“猪宝宝”请输出"Pig";若是“鼠宝宝”请输出"Mouse"。样例输入:
1 1
样例输出: Pig
#include<iostream>
using namespace std;
int main()
{
int month,day;
cin>>month>>day;
if(month==1&&day<=24)
cout<<"Pig";
else
cout<<"Mouse";
return 0;
}
3.6.2 写个“2” 题目描述:2020 年 2 月,小蓝参加“蓝桥杯大赛青少年创意编程 C++组”选拔赛。在
一个这么“2”的时间里参赛,小蓝一时高兴,忍不住在键盘上敲出了一个会写“2”的程
序。
输入:一个整数 n(3<=n<=100)
输出:一个由“*”组成的长、宽都是 n 的“2”字图形,具体请参见样例。
样例输入 1: 5
样例输出 1:
样例输入 2: 8
第 123 页 共 256 页
样例输出 2:
#include <iostream>
using namespace std;
int main( ) {
int n;
cin>>n;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{//第一行 第 n 行 i+j 的和等于 n+1
if(i==1||i==n||i+j==n+1)
cout<<"*";
else
cout<<" ";
}
cout<<endl;
}
return 0;
}
3.6.3 石头剪刀布
放假期间,小蓝与电脑对垒,玩起了一款经典的游戏:“石头剪刀布”。游戏规则
想必大家已经非常熟悉了:两边一样则为平局,否则石头胜于剪刀;剪刀胜于布;布
胜于石头。小蓝与电脑的对垒一共有 n 个回合,平局或败局得分为 0;胜局得分取
决于小蓝出手的阵容, 剪刀、石头、布各有不同的分值:
出手“石头”赢的话得 r 点分值; 出手“剪刀”赢的话得 s 点分值; 出手“布”赢的
话得 c 点分值;
但是,在第 i 回合中,小蓝不能使用在第(i-k)个回合中使用的阵容。 (在前 k
个回合中,小蓝可以使用任何阵容。)
在游戏开始之前,电脑已经事先安排好了每回合比赛的阵容,而小蓝居然未卜先
知了电脑的阵容!电脑的出手阵容用字符串 t 给出,如果 t 的第 i 个字符(1≤i≤n)
为 r,则代表电脑将在第 i 个回合中出手“石头”。同样,c 和 s 分别代表“布”和“剪刀”。
那么请你计算一下,小蓝在游戏中可以获得的最大分值是多少? 输入:
第 124 页 共 256 页
n k
r s c t
其中:n,k,r,s,c 都是整数,t 是字符串。2≤n≤20
1≤k≤n?1
1≤r,s,c≤1000
字符串 t 的长度是 n 输出:
小蓝在游戏中可以获得的最大分值。
6
样例输入:
5 2
8 7 6
rsrcr
样例输出:
27
样例说明:
机器出手的阵容是:石头、剪刀、石头、布、石头
则小蓝出手:布、石头、石头、剪刀、布,分值为 6+8+0+7+6=27 分
第 3 回合里,小蓝不能再出第(3-2=1)回合里出过的“布”了,所以选择了平局,
出手“石头”,得 0 分。
#include <iostream>
using namespace std;
int main( ) {
int n,k,r,s,c;
char str1[22],str2[22];
cin>>n>>k>>r>>s>>c>>str1;
int sum=0;
for(int i=0; i<k; i++) {
if(str1[i]=='r') {
str2[i]='c';
sum+=c;
} else if(str1[i]=='s') {
str2[i]='r';
sum+=r;
} else if(str1[i]=='c') {
str2[i]='s';
sum+=s;
第 125 页 共 256 页
}
}
for(int i=k; i<n; i++) {
if(str1[i]=='r') {
if(str2[i-k]=='c') str2[i]='r';
else {
str2[i]='c';
sum+=c;
}
} else if(str1[i]=='s') {
if(str2[i-k]=='r') str2[i]='s';
else {
str2[i]='r';
sum+=r;
}
} else if(str1[i]=='c') {
if(str2[i-k]=='s') str2[i]='c';
else {
str2[i]='s';
sum+=s;
}
}
}
cout<<sum;
return 0;
}
3.6.4 部分排序
一个数列 P 中有 n 个数。小蓝从中选择位置连续的 k 个数,并对这 k 个数进
行升序排列。求排序后的数列有多少种?
输入:
n k
P0 P1 ? Pn?1
其中:所有的输入都是整数,2≤n≤100,2≤k≤n,0≤Pi≤n?1,P0,P1,?,Pn?1 数值都不
相同。输出:
部分排序后数列的排列数。样例输入:
5 3
第 126 页 共 256 页
0 2 1 4 3
样例输出:
2
样例说明:从原数列抽取连续 3 个数排序后有 2 种可能性: (0,1,2,4,3) 和
(0,2,1,3,4)。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
//b 记录本次排序后的数列
//last 记录上次排序得到的数列
int a[N], b[N], last[N];
int n, k;
//检查两个数列是否相同
bool check(int a[], int b[]) {
for(int i = 0; i < n; i ++)
if(a[i] != b[i]) return false;
return true;
}
int main() {
cin >> n >> k;
for(int i = 0; i < n; i ++) cin >> a[i];
//将原数列 a 拷贝到 last 中
memcpy(last, a, sizeof a);
int sum = 0;
//枚举所有连续 k 个数的起始位置
for(int i = 0; i <= n - k; i ++) {
//将 a 拷贝到 b 中进行排序
memcpy(b, a, sizeof a);
sort(b + i, b + i + k);
//排序后与上一个序列不相同
if(!check(last, b)) sum ++;
//将 b 拷贝到 last
memcpy(last, b, sizeof b);
}
第 127 页 共 256 页
cout << sum << endl;
return 0;
}
3.6.5 题目的分数值
蓝桥杯 C++青少组的比赛有 n 个问题,现在请你给这 n 个问题分配分值。
n 个问题已经按从简单到困难排好序,第 i 个问题的分值是 Ai。n 个问题的分值
满足如下关系:
1≤A1≤A2≤…≤An≤n。不同的问题可以具有相同的分值。
主办方希望:解决更多问题的参赛者的排名更高。 因此,对于任何解决了 k
(1≤k≤n-1)个问题的参赛者,其分数总和一定要小于解决了任何 k + 1 个问题的参
赛者的分数总和。
你有几种分配分值的方法? 将答案对素数 m 取余后输出。输入:
整数 n 和 m
其中 2≤n≤5000,9×108<m<109 ,m 为素数。输出:
分值分配的方案数对 m 取余后的数字样例输入 1:
2 998244353
样例输出 1: 3
样例 1 说明:
2 个题的分值分配有 3 种方案: (1,1), (1,2), (2,2)。
样例输入 2: 3 998244353
样例输出 2: 7
样例 2 说明:
3 个题的分值分配有 7 种方案:(1,1,1), (1,2,2), (1,3,3), (2,2,2), (2,2,3), (2,3,3), (3,3,3)。
//动态规划题
#include<iostream>
#include<iomanip>
using namespace std;
int dp[502][502];
int main()
{
int n,m;
cin>>n>>m;
for(int k=1;k<=n;k++) dp[1][k] = k;
for(int i=2;i<=n;i++) // 后面还有几个数
{
第 128 页 共 256 页
for(int k=1;k<=n;k++) //当前阶段有多少种选择
{
if(k==1) dp[i][k] = dp[i-1][k];
else dp[i][k] =(dp[i][k-1] + dp[i-1][k]) % m;
}
}
int ans = 0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
int k1= min(i,n-j+1);
ans = (ans + dp[n-2][k1]) % m;
}
}
if(n==2) ans = 3;
cout<<ans<<endl;
return 0;
}
3.6.6 凑算式
B DEF
A + --- + ------- = 10
C GHI
这个算式中 A~I 代表 1~9 的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
答案:29
#include<stdio.h>
int ans = 0;
int num[10];
bool visit[10];
第 129 页 共 256 页
void Solve()
{
double sum = num[0] + (double)num[1] / num[2] +
(double)(num[3]*100+num[4]*10+num[5])/(num[6]*100+num[7]*10+num[8]);
if(sum == 10)
{
ans ++;
}
}
void dfs(int index)
{
if(index == 9)
{
Solve();
return ;
}
for(int i = 1 ; i < 10 ; i ++)
{
if(!visit[i])
{
visit[i] = true;
num[index] = i;
dfs(index+1);
visit[i] = false;
}
}
}
int main()
{
dfs(0);
printf("%d\n",ans);
return 0;
}
第 130 页 共 256 页
3.6.7 快速排序
排序在各种场合经常被用到。快速排序是十分常用的高效率的算法。
其思想是:先选一个“标尺”,用它把整个队列过一遍筛子,以保证:其左边的元
素都不大于它,其右边的元素都不小于它。这样,排序问题就被分割为两个子区间。
再分别对子区间排序就可以了。
下面的代码是一种实现,请分析并填写划线部分缺少的代码。
#include <stdio.h>
void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int partition(int a[], int p, int r)
{
int i = p;
int j = r + 1;
int x = a[p];
while(1){
while(i<r && a[++i]<x);
while(a[--j]>x);
if(i>=j) break;
swap(a,i,j);
}
______________________;
return j;
}
void quicksort(int a[], int p, int r)
{
if(p<r){
int q = partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}
第 131 页 共 256 页
int main()
{
int i;
int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
int N = 12;
quicksort(a, 0, N-1);
for(i=0; i<N; i++) printf("%d ", a[i]);
printf("\n");
return 0;
}
答案:swap(a,p,j)
3.6.8 抽签
X 星球要派出一个 5 人组成的观察团前往 W 星。
其中:
A 国最多可以派出 4 人。
B 国最多可以派出 2 人。
C 国最多可以派出 2 人。
.... 那么最终派往 W 星的观察团会有多少种国别的不同组合呢?
下面的程序解决了这个问题。
数组 a[] 中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
第 132 页 共 256 页
BCFFF
BCEFF
BCDFF
BCDEF
.... (以下省略,总共 101 行)
#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024
void f(int a[], int k, int m, char b[])
{
int i,j;
if(k==N){
b[M] = 0;
if(m==0) printf("%s\n",b);
return;
}
for(i=0; i<=a[k]; i++){
for(j=0; j<i; j++) b[M-m+j] = k+'A';
______________________; //填空位置
}
}
int main()
{
int a[N] = {4,2,2,1,1,3};
char b[BUF];
f(a,0,M,b);
return 0;
}
答案 f(a,k+1,m-j,b)或 f(a,k+1,m-i,b)
3.6.9 方格填数(DP)
如下的 10 个格子
+--+--+--+
第 133 页 共 256 页
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
填入 0~9 的数字。要求:连续的两个数字不能相邻。(左右、上下、对角都算相
邻)
一共有多少种可能的填数方案?请填写表示方案数目的整数。
答案是:1580
#include <stdio.h>
#include <math.h>
int flag[3][4]; //表示哪些可以填数
int mpt[3][4]; //填数
bool visit[10];
int ans = 0;
void init() //初始化
{
int i,j;
for(i = 0 ; i < 3 ; i ++)
for(j = 0 ; j < 4 ; j ++)
flag[i][j] = 1;
flag[0][0] = 0;
flag[2][3] = 0;
}
void Solve()
{
int dir[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};
int book = true;
for(int i = 0 ; i < 3 ; i ++)
{
for(int j = 0 ; j < 4; j ++)
{
//判断每个数周围是否满足
if(flag[i][j] == 0)continue;
第 134 页 共 256 页
for( int k = 0 ; k < 8 ; k ++)
{
int x,y;
x = i + dir[k][0];
y = j + dir[k][1];
if(x < 0 || x >= 3 || y < 0 || y >= 4 || flag[x][y] == 0) continue;
if(abs(mpt[x][y] - mpt[i][j]) == 1) book = false;
}
}
}
if(book) ans ++;
}
void dfs(int index)
{
int x,y;
x = index / 4;
y = index % 4;
if( x == 3)
{
Solve();
return;
}
if(flag[x][y])
{
for(int i = 0 ; i < 10 ; i ++)
{
if(!visit[i])
{
visit[i] = true;
mpt[x][y] = i;
dfs(index+1);
visit[i] = false;
}
}
}
第 135 页 共 256 页
else
{
dfs(index+1);
}
}
int main()
{
init();
dfs(0);
printf("%d\n",ans);
return 0;
}
3.6.10剪邮票
如图 1.jpg, 有 12 张连在一起的 12 生肖的邮票。
现在你要从中剪下 5 张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,图 2.jpg,图 3.jpg 中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
答案:116
#include <stdio.h>
#include <string.h>
int mpt[3][4];
int mpt_visit[3][4];
int num[6];
int have[13];
int visit[13];
int ans = 0;
int Count = 0;
void init()
{
int k = 1;
for(int i = 0 ; i < 3 ; i ++)
for(int j = 0 ; j < 4 ; j ++)
第 136 页 共 256 页
{
mpt[i][j] = k;
k ++;
}
}
int dir[4][2] = {0,1,0,-1,-1,0,1,0};
//判断五个数是否能连在一起
void dfs_find(int x,int y)
{
for(int i = 0 ; i < 4 ; i++)
{
int tx,ty;
tx = x + dir[i][0];
ty = y + dir[i][1];
if(tx < 0 || tx >= 3 || ty < 0 || ty >= 4) continue;
if(have[mpt[tx][ty]] == 0 || mpt_visit[tx][ty])continue;
mpt_visit[tx][ty] = 1;
Count ++;
dfs_find(tx,ty);
}
}
void Solve()
{
int i;
memset(have,0,sizeof(have));
memset(mpt_visit,0,sizeof(mpt_visit));
for(i = 1; i < 6 ; i ++) have[num[i]] = 1;
for(i = 0 ; i < 12 ; i ++)
{
int x,y;
x = i / 4;
y = i % 4;
if(have[mpt[x][y]])
{
Count = 1;
第 137 页 共 256 页
mpt_visit[x][y] =1;
dfs_find(x,y);
break;
}
}
if(Count == 5)
{
ans ++;
}
}
//创建 5 个数的组合
void dfs_creat(int index)
{
if(index == 6)
{
Solve();
return;
}
for(int i = num[index-1] + 1; i < 13 ; i ++)
{
if(!visit[i])
{
visit[i] = true;
num[index] = i;
dfs_creat(index+1);
visit[i] = false;
}
}
}
int main()
{
init();
dfs_creat(1);
printf("%d\n",ans);
第 138 页 共 256 页
return 0;
}
3.6.11四平方和
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多 4 个正整数的平方和。
如果把 0 包括进去,就正好可以表示为 4 个数的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对 4 个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
程序输入为一个正整数 N (N<5000000)
要求输出 4 个非负整数,按从小到大排序,中间用空格分开
例如,输入:
5
则程序应该输出:
0 0 1 2
再例如,输入:
12
则程序应该输出:
0 2 2 2
再例如,输入:
773535
则程序应该输出:
1 1 267 838
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main 函数需要返回 0
注意: 只使用 ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特
殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设
置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
第 139 页 共 256 页
答案:
方法一:
#include <stdio.h>
#include <math.h>
int main()
{
int n;
int flag = false;
scanf("%d",&n);
for(int i = 0 ; i * i <= n ; i ++)
{
for(int j = 0 ; j * j <= n ; j ++){
for(int k = 0 ; k * k <= n ; k ++)
{
int temp = n - i*i - j*j - k*k;
double l = sqrt((double) temp);
if(l == (int)l )
{
printf("%d %d %d %d\n",i,j,k,(int)l);
flag = true;
break;
}
}
if(flag)break;
}
if(flag)break;
}
return 0;
}
方法二:
#include <stdio.h>
#include <math.h>
int mpt[5000010] ={0}; //mpt[i] = 1 表示 i 能够用两个完全平方数相加而得。
int n;
void init()
{
第 140 页 共 256 页
for(int i = 0 ; i*i <= n ; i ++)
for(int j = 0 ; j*j <=n ; j ++)
if(i*i+j*j <= n) mpt[i*i+j*j] = 1;
}
int main()
{
int flag = false;
scanf("%d",&n);
init();
for(int i = 0 ; i * i <= n ; i ++)
{
for(int j = 0 ; j * j <= n ; j ++){
if(mpt[n - i*i - j*j] == 0) continue; //如果剩下的差用两个完
全平方数不能组合出来就不继续
for(int k = 0 ; k * k <= n ; k ++)
{
int temp = n - i*i - j*j - k*k;
double l = sqrt((double) temp);
if(l == (int)l )
{
printf("%d %d %d %d\n",i,j,k,(int)l);
flag = true;
break;
}
}
if(flag)break;
}
if(flag)break;
}
return 0;
}
3.6.12交换瓶子
有 N 个瓶子,编号 1 ~ N,放在架子上。
比如有 5 个瓶子:
2 1 3 5 4
第 141 页 共 256 页
要求每次拿起 2 个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换 2 次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数 N(N<10000), 表示瓶子的数目
第二行:N 个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
例如,输入:
5
3 1 2 5 4
程序应该输出:
3
再例如,输入:
5
5 4 3 2 1
程序应该输出:
2
#include<iostream>
using namespace std;
int a[10005];//a[i]表示位置 i 的瓶子编号
int b[10005];//b[i]表示 i 号瓶子的位置。没有这个数组的话,需要在 a 数组中循
环找到 i 号瓶子(O(n)),用这个数组的话是 O(1)
int main() {
int N;
int i;
int id;
int sum;
//设瓶子 1 为位置 i 的瓶子,瓶子 2 为 i 号瓶子
int id1, id2; //瓶子 1 的编号,瓶子 2 的编号
int pos1, pos2; //瓶子 1 的位置,瓶子 2 的位置
while (cin >> N) {
for (i = 1; i <= N; ++i) {
cin >> id;
a[i] = id; //位置 i 放 id 号瓶子
第 142 页 共 256 页
b[id] = i; //id 号瓶子放到位置 i
}
sum = 0;
for (i = 1; i <= N; ++i) { //位置从 1 遍历到 N
if (a[i] == i)continue; //位置 i 放的是 i 号瓶子
//否则,瓶子 2 与瓶子 1 交换
id1 = a[i];
pos1 = i;
id2 = i;
pos2 = b[i]; //没有 b 数组的话,需要在 a 数组中找到 i 号瓶子
++sum;
//瓶子 1 放到瓶子 2 的位置
a[pos2] = id1; //瓶子 2 的位置(pos2)放瓶子 1(id1)
b[id1] = pos2; //瓶子 1(id1)放到瓶子 2 的位置(pos2)
//瓶子 2 放到瓶子 1 的位置
a[pos1] = id2; //瓶子 1 的位置放瓶子 2
b[id2] = pos1; //瓶子 2 放到瓶子 1 的位置
}
cout << sum << endl;
}
return 0;
}
3.6.13最大比例
X 星球的某个大奖赛设了 M 级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式:
第一行为数字 N (0<N<100),表示接下的一行包含 N 个正整数
第二行 N 个正整数 Xi(Xi<1 000 000 000 000),用空格分开。每个整数表示调查到
的某人的奖金数额
要求输出:
第 143 页 共 256 页
一个形如 A/B 的分数,要求 A、B 互质。表示可能的最大比例系数
测试数据保证了输入格式正确,并且最大比例是存在的。
例如,输入:
3
1250 200 32
程序应该输出:
25/4
再例如,输入:
4
3125 32 32 200
程序应该输出:
5/2
再例如,输入:
3
549755813888 524288 2
程序应该输出:
4/1
答案:
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
#define LL long long
struct fs
{
LL up,down;
};
int n;
LL arr[110];
fs Fs[110];
bool cmp(LL a,LL b)
{
return a > b;
}
第 144 页 共 256 页
LL Gcd(LL a,LL b)
{
if( b == 0 )return a;
return Gcd(b,a%b);
}
LL Get(LL a, LL b)
{
if( a < b) a ^= b ^= a ^= b;
LL v[30];
queue<LL>team;
if( a == b || a / b == a) return b;
v[0] = a, v[1] = b;
v[2] = a / b;
int top = 3,i,j;
team.push(a/b);
while(team.size())
{
LL now = team.front();
team.pop();
for(i = 0 ; i < top ; i ++)
{
LL temp = (v[i] > now) ? v[i] / now : now / v[i];
bool find = false;
for(j = 0 ; j < top ; j ++)
if( v[j] == temp) find = true;
if(find == true) continue;
team.push(temp);
v[top++] = temp;
}
}
LL ans = v[0];
for(i = 0 ; i < top ; i ++)
if(v[i] != 1)
{
ans = v[i];
break;
第 145 页 共 256 页
}
for(i = 0 ; i < top ; i ++)
if( v[i] < ans && v[i] != 1) ans = v[i];
return ans;
}
int main()
{
int i,j;
scanf("%d",&n);
for(i = 0 ; i < n ; i ++) scanf("%lld",&arr[i]);
sort(arr,arr+n,cmp);
int top = 1;
for(i = 1; i < n ; i ++)
if(arr[i] != arr[i-1]) arr[top++] = arr[i];
n = top;
for(i = 0 ; i < n - 1; i ++)
{
LL gcd = Gcd(arr[i],arr[i+1]);
Fs[i].up = arr[i] / gcd;
Fs[i].down = arr[i+1] / gcd;
}
LL x = Fs[0].up;
for(i = 0 ; i < n - 1 ; i ++)
x = Get(x,Fs[i].up);
LL y = Fs[0].down;
for(i = 0 ; i < n - 1; i ++)
y = Get(y,Fs[i].down);
printf("%lld/%lld\n",x,y);
return 0;
}
3.6.14外卖店优先级
“饱了么”外卖系统中维护着 N 家外卖店,编号 1 ~ N。每家外卖店都有 一个优
先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减 到 0;
而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果 优先级
第 146 页 共 256 页
小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优 先
缓存中。
输入
第一行包含 3 个整数 N、M 和 T。
以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到一个
订单。
输出
输出一个整数代表答案。
样例输入
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
样例输出
1
样例解释
6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6, 加
入优先缓存。所以是有 1 家店 (2 号) 在优先缓存中。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m, t, ts, id, cnt = 0;
int level;
bool is_priority = false;
vector<int> v[100005];
cin >> n >> m >> t;
for (int i = 1; i <= m; i++)
{
cin >> ts >> id;
v[id].push_back(ts);
}
第 147 页 共 256 页
for (int i = 1; i <= n; i++)
{
if (v[i].size() == 0)
continue;
sort(v[i].begin(), v[i].end());
is_priority = false;
level = 2;
for (int j = 1; j < v[i].size(); j++)
{
if (v[i][j] - v[i][j - 1] <= 1)
level += 2;
else
{
level -= (v[i][j] - v[i][j - 1] - 1);
if (level < 0)
level = 0;
if (level <= 3)
is_priority = false;
level += 2;
}
if (level > 5)
{
is_priority = true;
}
}
int k = v[i][v[i].size() - 1];
level -= (t - k);
if (level <= 3)
is_priority = false;
if (is_priority == true)
cnt++;
}
cout << cnt << endl;
return 0; }

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值