。。。。
SMU 2024 spring 天梯赛1
https://pintia.cn/problem-sets/1767462526651166720
L1-3 小孩子才做选择,大人全都要
收益要大于狗找到的才能狗算赚到。不是吃到就算赚到。
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int x,y;
cin>>x>>y;
int gou=max(x,y);//看最多的情况。
if(gou>0)//分析存在大于零的情况
{
cout<<gou<<" ";
if(x+y>=gou)//如果总数大于gou,那么另一个数>0,不存在空盒。狗能赚到
{
cout<<x+y<<endl;
cout<<"^_^"<<endl;
}else if(x+y<gou&&x+y>0)//收益<=gou。存在空盒可以装满。但吃不到。
{
cout<<x+y<<endl;
cout<<"T_T"<<endl;
}else//装不满还要买。一点都没吃
{
cout<<"0"<<endl;
cout<<"T_T"<<endl;
}
}else if(gou<0)//gou都小于0,一点狗粮没有。
{
cout<<"0"<<" "<<"0"<<endl;
cout<<"-_-"<<endl;
}
return 0;
}
7-7 静静的推荐
点击看题
L1-8 静静的推荐 (20 分)
天梯赛结束后,某企业的人力资源部希望组委会能推荐
一批优秀的学生,这个整理推荐名单的任务就由静静姐负责
。企业接受推荐的流程是这样的:
①只考虑得分不低于 175 分的学生;
②一共接受 K 批次的推荐名单;
③同一批推荐名单上的学生的成绩原则上应严格递增;
④如果有的学生天梯赛成绩虽然与前一个人相同,
但其参加过 PAT 考试,且成绩达到了该企业的面试分数线,
则也可以接受。
给定全体参赛学生的成绩和他们的 PAT 考试成绩,
请你帮静静姐算一算,她最多能向企业推荐多少学生?
输入格式:
输入第一行给出 3 个正整数:N(≤105)为参赛学生人数,
K(≤5×103)为企业接受的推荐批次,S(≤100)为该企业的 PAT 面试分数线。
随后 N 行,每行给出两个分数,依次为
一位学生的天梯赛分数(最高分 290)和 PAT 分数(最高分 100)。
输出格式:
在一行中输出静静姐最多能向企业推荐的学生人数。
输入样例:
10 2 90
203 0
169 91
175 88
175 0
175 90
189 0
189 0
189 95
189 89
256 100
输出样例:
8
样例解释:
第一批可以选择 175、189、203、256 这四个分数的学生各一名,
此外 175 分 PAT 分数达到 90 分的学生和 189 分 PAT 分数达到 95 分的学生
可以额外进入名单。
第二批就只剩下 175、189 两个分数的学生各一名可以进入名单了。
最终一共 8 人进入推荐名单。
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int n,k,s;
cin>>n>>k>>s;
vector<pair<int,int>>stu(n);
int sum=0;
map<int,int>u;
for(int i=0;i<n;i++)
{
cin>>stu[i].first>>stu[i].second;
if(stu[i].first>=175&&stu[i].second>=s)
{
sum++;
//如果一个人的天梯成绩和考试成绩都满足要求,他一定可以被选上
}if((u.find(stu[i].first)==u.end()||u[stu[i].first]<k)&&stu[i].first>=175&&stu[i].second<s)
{
//如果这个学生的成绩是第一次出现,或者出现次数小于批次(每一批的第一人)。
//那么他的成绩要大于175,并且考试成绩无法满足要求。均满足的已经被选走。
sum++;
u[stu[i].first]++;
}
}
cout<<sum;
return 0;
}
7-9 彩虹瓶
点击看题
彩虹瓶的制作过程(并不)是这样的:
先把一大批空瓶铺放在装填场地上,
然后按照一定的顺序将每种颜色的小球均匀撒到这批瓶子里。
假设彩虹瓶里要按顺序装 N 种颜色的小球
(不妨将顺序就编号为 1 到 N)。
现在工厂里有每种颜色的小球各一箱,
工人需要一箱一箱地将小球从工厂里搬到装填场地。
如果搬来的这箱小球正好是可以装填的颜色,就直接拆箱装填;
如果不是,就把箱子先码放在一个临时货架上,
码放的方法就是一箱一箱堆上去。当一种颜色装填完以后,
先看看货架顶端的一箱是不是下一个要装填的颜色,
如果是就取下来装填,否则去工厂里再搬一箱过来。
如果工厂里发货的顺序比较好,工人就可以顺利地完成装填。
例如要按顺序装填 7 种颜色,
工厂按照 7、6、1、3、2、5、4 这个顺序发货,
则工人先拿到 7、6 两种不能装填的颜色,
将其按照 7 在下、6 在上的顺序堆在货架上;
拿到 1 时可以直接装填;拿到 3 时又得临时码放在 6 号颜色箱上;
拿到 2 时可以直接装填;随后从货架顶取下 3 进行装填;
然后拿到 5,临时码放到 6 上面;最后取了 4 号颜色直接装填;
剩下的工作就是顺序从货架上取下 5、6、7 依次装填。
但如果工厂按照 3、1、5、4、2、6、7 这个顺序发货,
工人就必须要愤怒地折腾货架了,因为装填完 2 号颜色以后,
不把货架上的多个箱子搬下来就拿不到 3 号箱,就不可能顺利完成任务。
另外,货架的容量有限,如果要堆积的货物超过容量,
工人也没办法顺利完成任务。
例如工厂按照 7、6、5、4、3、2、1 这个顺序发货,
如果货架够高,能码放 6 只箱子,那还是可以顺利完工的;
但如果货架只能码放 5 只箱子,工人就又要愤怒了……
本题就请你判断一下,工厂的发货顺序能否让工人顺利完成任务。
输入格式:
输入首先在第一行给出 3 个正整数,
分别是彩虹瓶的颜色数量 N(1<N≤10^3)、
临时货架的容量 M(<N)、
以及需要判断的发货顺序的数量 K。
随后 K 行,每行给出 N 个数字,
是 1 到N 的一个排列,对应工厂的发货顺序。
一行中的数字都以空格分隔。
输出格式:
对每个发货顺序,如果工人可以愉快完工,
就在一行中输出 YES;否则输出 NO。
输入样例:
7 5 3
7 6 1 3 2 5 4
3 1 5 4 2 6 7
7 6 5 4 3 2 1
输出样例:
YES
NO
NO
思路:
设置一个aim变量代表应该装填的序号,aim的范围是从1开始到小球总个数,如果输入的n与aim不等,就把这个小球放上货架;如果相等,让aim++,并且与货架最上面的小球进行比较,如果相等,就将这个小球拿下来且aim++,如果不等,进入下一次输入。
每次循环的最后进行对是否能顺利装填条件的判断(大于货架容量、aim超出、货架出现序号小的小球在下,都属于不能顺利装填)
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int n,m,K;
cin>>n>>m>>K;
while(K--)
{
int flag=0,a[10010];
stack<int>s;//货架
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int p=1,need=1;//p用来分析数组,need用来分析产品的需求。
while(need<=n)
{
if(a[p]==need)//如果拿进来的刚好是需要的,那么就直接放进去,数组和产品都++。
{
p++;
need++;
}else if(!s.empty()&&s.top()==need)
//如果货架不是空的,并且货架最上面的就是我需要的,就搬下来。
//如果货架最上面不是我需要的(也许我需要的被压在货架下面)我不会去搬多余的货把压下面的货找到(生气)。
//而是直接继续下一个箱子
{
s.pop();
need++;
}else if(s.size()<m)
//如果货架不是满的就把并且没有满足前面的要求,就把箱子放货架上去。
{
s.push(a[p]);
p++;
}else//货架满了,直接退出。
{
flag=1;
break;
}
}
if(flag)
{
cout<<"NO"<<endl;
}else
{
cout<<"YES"<<endl;
}
}
return 0;
}
L2-3 龙龙送外卖
点击看题
龙龙是“饱了呀”外卖软件的注册骑手,负责送帕特小区的外卖。
帕特小区的构造非常特别,都是双向道路且没有构成环 ——
你可以简单地认为小区的路构成了一棵树,根结点是外卖站,
树上的结点就是要送餐的地址。
每到中午 12 点,帕特小区就进入了点餐高峰。一开始,
只有一两个地方点外卖,龙龙简单就送好了;但随着大数据的分析,
龙龙被派了更多的单子,也就送得越来越累……
看着一大堆订单,龙龙想知道,从外卖站出发,
访问所有点了外卖的地方至少一次(这样才能把外卖送到)
所需的最短路程的距离到底是多少?每次新增一个点外卖的地
址,他就想估算一遍整体工作量,这样他就可以搞明白新增一个地址给他带来了多少负担。
输入格式:
输入第一行是两个数 N 和 M (2≤N≤10^5, 1≤M≤10^5),
分别对应树上节点的个数(包括外卖站),以及新增的送餐地址的个数。
接下来首先是一行 N 个数,第 i 个数表示
第 i 个点的双亲节点的编号。节点编号从 1 到 N,
外卖站的双亲编号定义为 −1。
接下来有 M 行,每行给出一个新增的送餐地点的编号 Xi。
保证送餐地点中不会有外卖站,但地点有可能会重复。
为了方便计算,我们可以假设龙龙一开始一个地址的外卖都不用送,
两个相邻的地点之间的路径长度统一设为 1,且从外卖站出发可以访问到所有地点。
注意:所有送餐地址可以按任意顺序访问,且完成送餐后无需返回外卖站。
输出格式:
对于每个新增的地点,在一行内输出题目需要求的最短路程的距离。
输入样例:
7 4
-1 1 1 1 2 2 3
5
6
2
4
输出样例:
2
4
4
6
#include<bits/stdc++.h>
using namespace std;
#define int long long
set<int>st;
const int N=1e5+10;
int edge[N];
int max_length=0;
int dis[N];
// 深度优先搜索函数,cur为当前结点,len为当前路径长度
int dfs(int cur,int len)
{
// 如果当前结点在集合st中,表示已经访问过,更新最大路径长度并返回2倍的len
if(st.count(cur)){
max_length=max(max_length,dis[cur]+len);
return 2*len;
}
// 继续深度优先搜索
int res=dfs(edge[cur],len+1);
st.insert(cur);// 将当前结点加入集合st
dis[cur]=dis[edge[cur]]+1;// 更新当前结点的距离
return res;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int n,m;
cin>>n>>m;
// 输入各个结点的双亲节点编号
for(int i=1;i<=n;i++)
{
cin>>edge[i];
if(edge[i]==-1)
{
st.insert(i);
dis[i]=0;
}
}
int ans=0;
// 处理新增的送餐地点
for(int i=1;i<=m;i++)
{
int d;
cin>>d;
ans+=dfs(d,0);// 深度优先搜索,并累加结果
cout<<ans-max_length<<endl;// 输出结果(总距离减去最大路径长度)
}
return 0;
}
牛客挑战赛73
https://ac.nowcoder.com/acm/contest/76652#question
S 老师的公式
S 老师丢给你了一个简单的数学问题:
求
请你求出答案。
输入描述:
输入格式
一行一个整数 (1≤n≤10^6)。
输出描述:
一行一个整数表示答案。
示例1
输入
3
输出
6
说明
gcd(1+2+3,1⋅2⋅3)=gcd(6,6)=6
思路:先把s=n*(n+1)/2算出来,s<=10^12.
然后根据gcd(a,b)=gcd(a,b mod a),用循环计算,每次乘法后取模,中间结果恰好在10^12 * 10^6 在long long范围内。
最后再对long long求一次gcd就好。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=1e5+5;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
int n;
cin>>n;
int p=1;
int a=n*(n+1)/2;
for(int i=1;i<=n;i++)
{
p=p*i%a;
}
int x=gcd(p,a);
cout<<x<<endl;
return 0;
}
c++各种数据类型的取值范围
同余定理
①如果 a%b = c, 则有(a+kb)%b = c; (k为非0整数)
②如果 a%b = c, 则有(ka)%b = kc%b; (k为正整数)
③(a+b)%c = ((a%c) + (b%c)) % c;
④(ab)%c = ((a%c)(b%c)) % c;
⑴整数N被2或5除的余数等于N的个位数被2或5除的余数;
⑵整数N被4或25除的余数等于N的末两位数被4或25除的余数;
⑶整数N被8或125除的余数等于N的末三位数被8或125除的余数;
⑷整数N被3或9除的余数等于其各位数字之和被3或9除的余数;
⑸整数N被11除的余数等于N的奇数位数之和与偶数位数之和的差被11除的余数;
S 老师的求和
S 老师是求和大师,熟练运用求和符号 (Σ) 。
他给定整数 a,b,x,并定义
![](https://img2024.cnblogs.com/blog/3381412/202403/3381412-20240317114950927-66599251.png)
不断进行取余操作结果不变。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
int add(int a,int b)
{
return (a+b)%mod;
}
int mul(int a,int b)
{
return (a*b)%mod;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int t;
cin>>t;
while(t--)
{
int a,b,x;
cin>>a>>b>>x;
int l1=add(mul(a,x),b);
int l2=0,l3=0,l4=0;
for(int i=1;i<=x;i++)
{
l2=add(l2,add(mul(a,i),b));
l3=add(l3,l2);
l4=add(l4,l3);
}
cout<<l1<<" "<<l2<<" "<<l3<<" "<<l4<<endl;
}
return 0;
}
第十四届南京工程学院程序设计及应用竞赛校外同步赛
https://ac.nowcoder.com/acm/contest/77338#question
H 老师的竞赛宣讲
#include<bits/stdc++.h>
using namespace std;
struct node{
int id;
int pass;
int time;
int rank;
};
bool cmp(const node&a,const node&b)
{
if(a.pass!=b.pass)
{
return a.pass>b.pass;
}if(a.time!=b.time)
{
return a.time<b.time;
}
return a.id<b.id;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<node> stu(m);
for(int i=0;i<m;i++)
{
stu[i].id=i+1;
int pass1=0;
int times=0;
for(int j=0;j<n;j++)
{
int x,y,pass2;
cin>>x>>y>>pass2;
if(pass2==1)
{
pass1++;
times+=y+(x-1)*20;
}
}
stu[i].pass=pass1;
stu[i].time=times;
}
sort(stu.begin(),stu.end(),cmp);
for(int i=0,rank=1;i<m;i++)
{
if(i>0 && (stu[i].pass!=stu[i-1].pass||
stu[i].time!=stu[i-1].time))
{
rank=i+1;
}
stu[i].rank=rank;
}
sort(stu.begin(),stu.end(),[](const node&a,const node&b){return a.id<b.id;});
for(const auto&stu1:stu)
{
cout<<stu1.rank<<"\n"<<stu1.pass<<"\n"<<stu1.time<<"\n";
}
return 0;
}
'\n'要比endl来的快。