链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目a
在风景如画,美女如云的SMU生活学习一年后,多金的花样少年JolerJolerJoler练成了见女生必送鲜花的浪漫绝技。这一天,JolerJolerJoler要去见PrincessFunPrincess FunPrincessFun,他们在一条长度为nnn的,有n+1n+1n+1个点的笔直的路上,JolerJolerJoler在第000点上,PrincessFunPrincess FunPrincessFun在第nnn点上,第111个点到第n−1n-1n−1个点上每个点都有一家花店,第iii家花店以aia_iai的价格出售美丽值为bib_ibi的花(每家花店都只出售一种花)。JolerJolerJoler希望送给PrincessFunPrincess FunPrincessFun最美丽的花,但他提前并不知道每家花店的花的美丽值。因此他想出了一个“货比三家”买花算法:
- 会买下第一家的花。
- 之后每遇到一家花店,就把当前这家花店的花和自己手里的花进行比较,如果这家花店的花比自己手里的花更美丽,就去下一家花店观察花店的美丽值(若存在)。简而言之,当前在第iii个花店,会比较第iii个花店售出花的美丽值,如果更美丽,就去看第i+1i+1i+1个花店售出花的美丽值。买下这两家花店中最美丽的花(如果一样美丽,则买下便宜的一家花店的花)来替换自己手中的花并且下一次从第i+2i+2i+2家花店开始看,继续以上步骤。
请你计算出JolerJolerJoler最终需要花多少钱。
输入描述:
共3行: 第一行包含一个整数nnn(222 ≤\leq≤ nnn ≤\leq≤ 100000100000100000), 表示路的长度(路上有n+1n+1n+1个点)。 第二行包含n−1n-1n−1个整数ai(1≤ai≤109)a_i(1\le a_i \le 10^9)ai(1≤ai≤109),表示第iii家花店出售花的价格。 第三行包含n−1n-1n−1个整数bi(1≤bi≤109)b_i(1\le b_i \le 10^9)bi(1≤bi≤109),表示第iii家花店出售的花的美丽值。
输出描述:
共一行,输出按照题面中的方法,JolerJolerJoler最终会花多少钱。
示例1
输入
复制5 1 3 2 5 2 3 4 1
5 1 3 2 5 2 3 4 1
输出
复制3
3
思路:一眼看上去就是模拟题
草纸上可发现是三个为一组模拟(大多数模拟题也有几个为一组进行模拟,或者拆分成固定数目的小组进行模拟,毕竟大问题不能一直模拟鸭)
代码:记住i++;
难度:签到题
ac如下
//模拟题,全看代码结构和实现 #include <bits/stdc++.h> using namespace std; typedef long long ll; ll n,ans,beauty; ll a[100008];//价格 ll b[100008];//美丽值 int main(){ cin>>n; for(int i=1;i<n;i++) cin>>a[i]; for(int i=1;i<n;i++) cin>>b[i]; ans=a[1]; beauty=b[1]; for(int i=2;i<n;i++){ if(beauty<b[i]){ if(b[i]<b[i+1]){ ans+=a[i+1]; beauty=b[i+1]; } else if(b[i]>b[i+1]){ ans+=a[i]; beauty=b[i]; } else { ans+=min(a[i],a[i+1]); beauty=b[i]; } i++; } } cout<<ans<<endl; }
题目b
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
又是一年一度的新生校赛,但是acmacmacm集训队的sunshinesunshinesunshine关注的重点却不仅仅是校赛,因为校赛结束了意味着sunshinesunshinesunshine不久之后就可以在春节的时候回家去找好朋友(以下称呼为小www)一起玩,这样就不会寂寞了,好耶!
sunshinesunshinesunshine和小www的家乡是美丽的河南长垣。这里有纷繁复杂的公交线路,但是总共有nnn个站点(站点编号为1~nnn)。sunshinesunshinesunshine每次都坐公交去找小www,在寒假的某一天,sunshinesunshinesunshine和小www约定在小www所在的站点集合,sunshinesunshinesunshine在编号为1的站点,小www在编号为xxx的站点,由于公交车从一个站点uuu到相邻的站点vvv,需要花费时间ttt。但是小www每次所在位置都不一定(xxx不是固定的站点编号),因此sunshinesunshinesunshine想询问qqq次,每次sunshinesunshinesunshine想预先知道坐公交车去和小www集合在路上花费的最短时间(保证从1开始可以到任何站点)。
输入描述:
第1行给出nnn和mmm分别表示公交站点数和站点相邻的数量。 接下来的mmm行给出u,v,tu,v,tu,v,t。 表示公交车从站点uuu到站点vvv所需要的时间为ttt。 第m+1m+1m+1行一个数字qqq,代表qqq次询问。 接下来qqq行,每行给出一个xxx,代表小www所在的公交站点。
输出描述:
对于每次询问输出从站点1到站点xxx所需要的最短时间。 数据范围: 1≤n≤1000,n−1≤m≤n∗(n−1)21 \le n \le 1000,n-1 \le m \le \frac{n*(n-1)}{2}1≤n≤1000,n−1≤m≤2n∗(n−1) 1≤t≤109,1≤q≤500,1≤x≤n1 \le t \le 10^9,1 \le q \le 500,1 \le x \le n1≤t≤109,1≤q≤500,1≤x≤n
示例1
输入
复制3 3 1 2 1 2 3 1 1 3 3 3 1 2 3
3 3 1 2 1 2 3 1 1 3 3 3 1 2 3
输出
复制0 1 2
0 1 2
说明
从编号为1的站点出发,位置没有变,最短时间为0。 从编号为1的站点出发,到编号为2的站点,如果走1 – 2,时间花费为1,但是1 – 3 – 2 时间花费为4,因此最短时间为1。 从编号为1的站点出发,到编号为3的站点,如果走1 – 3,时间花费为3,但是1 – 2 – 3 时间花费为2,因此最短时间为2。
思路见代码:
//bfs模板,初始化,进行标记,判断接下来的行动,进行标记,边界条件退出
//一般用优先队列,队列
//存储图邻接链表用vector
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int inf = 123456789;
int n,m,t;
ll u,v,w;
bool vis[maxn];
ll dis[maxn];
struct node{
ll v,w;
bool operator < (const node &a) const {
return a.w<w;
}
};
vector<node>mapn[maxn];
priority_queue <node> q;
void bfs(){
dis[1]=0;
q.push(node{1,0});
while(!q.empty()){
node tmp=q.top();
q.pop();
int x=tmp.v;
if(vis[x]) continue;
vis[x]=1;
int len=mapn[x].size();
for(int i=0;i<len;i++){
int to=mapn[x][i].v;
if(dis[to]>mapn[x][i].w+dis[x]){
dis[to]=mapn[x][i].w+dis[x];
if(!vis[to]){
q.push((node){to,dis[to]});
}
}
}
}
}
int main(){
memset(dis,inf,sizeof(dis));
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
mapn[u].push_back(node{v,w});
mapn[v].push_back(node{u,w});
}
bfs();
int tmp,q;
cin>>q;
for(int i=1;i<=q;i++){
cin>>tmp;
cout<<dis[tmp]<<"\n";}
return 0;
}
难度:一道签到题
补充知识点:
存储无向图时可使用邻接链表
题目c:我看不懂大佬的思路啊
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
ACM集训队的sunshinesunshinesunshine在高中时期,语文成绩很差,因此经常被语文老师叫起来背作文,不能完整地背出来作文就要去抄写文言文。现在正在写本题题意的sunshinesunshinesunshine仍然能想起来高中语文老师的那句“背不出来就抄写10遍《逍遥游》”,那天的风贼大,内心一片萧索。
有一次,sunshinesunshinesunshine连续nnn天被语文老师提问,惩罚就是罚抄xxx次文言文sss,当然sunshinesunshinesunshine的记忆力不太好,所以每次都被罚抄文言文了(默默哭泣.jpg)。现在有qqq次询问,每次询问sunshinesunshinesunshine想知道从第LLL天到第RRR天(L≤RL \le RL≤R)某个文言文被抄写了多少遍。
输入描述:
第一行给出一个正整数nnn(1≤n≤10001 \le n \le 10001≤n≤1000)。 接下来nnn行,每行给出第iii天(1≤i≤n1 \le i \le n1≤i≤n)被罚抄的文言文标题字符串sss(长度不超过10)和被罚抄的次数xxx( 1≤x≤1091\le x \le 10^91≤x≤109)。 第n+2n+2n+2行,给出询问的次数q(1≤q≤106q(1 \le q \le 10^6q(1≤q≤106)。请注意输入量非常大,请避免使用cin、cout! 接下来qqq行,每行给出一个Li,Ri(1≤Li,Ru≤n)L_i,R_i ( 1 \le L_i , R_u \le n)Li,Ri(1≤Li,Ru≤n),和一个不包含空格的字符串sis_isi,表示询问LiL_iLi天到RiR_iRi天抄了sis_isi这个文言文多少次。
输出描述:
对于每次询问,请输出查询的答案。
示例1
输入
复制5 xyy 10 xyy 10 qx 10 xyy 10 qx 10 1 1 5 xyy
5 xyy 10 xyy 10 qx 10 xyy 10 qx 10 1 1 5 xyy
输出
复制30
30
说明
第一天到第五天中,第1,2,5天分别抄写了十遍xyy(逍遥游)共计30遍。
思路:最开始就是直接用map<string,int>mapn[n]开一个数组
大概是vector<int>mapn[n]的形式是数组套数组
对于map[n]的理解就是数组套映射
map[n][s]
而且这道题就先用char输入,再转成string才能符合map定义
呜呜呜我果然是个菜鸡(学哥这个时候应该睡了呜呜呜)
为啥cin会超时,要补知识点了)
#include <bits/stdc++.h> using namespace std; const long long N = 1e3 + 10; unordered_map<string, long long> ma[N]; int main() { long long n; cin >> n; for (long long i=1;i<=n;i++) { char t[15]; long long num; scanf("%s%lld", t, &num); string s = t; ma[i] = ma[i - 1]; ma[i][s] += num; } long long q; cin >> q; while (q--) { long long l, r; char t[15]; scanf("%lld%lld%s", &l, &r, t); string s = t; printf("%lld\n", ma[r][s] - ma[l - 1][s]); } return 0; }
代码如下
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string,int> mp;
int n,l,r;
int q;
string s;
ll day[1010][1010];
int t,i,j;
int main(){
cin>>n;
ll tmp;
int count = 1;
memset(day,0,sizeof(day));
for(int i=1;i<=n;i++){
cin>>s>>tmp;
if(!mp.count(s)){
mp[s] = count++;
}
int k = mp[s];
day[i][k] += tmp;
}
//这个数是第几天出现的,出现了几次,每次抄了多少要存清楚
for(int i=1;i<count;i++){
for(int j=1;j<=n;j++){
day[j][i] += day[j-1][i];
}
cin>>q;
while(q--){
cin>>l>>r>>s;
if(mp.count(s)){
int k = mp[s];
cout<<day[r][k] - day[l-1][k]<<endl;
}
else {
cout<<"0\n";
}
}
return 0;
}//暂时没读懂大佬的代码qaq为啥不直接开个数组嘞
题目d
又是一道模拟大水题
如果要看plus般,那就找抢修文物吧(得先考虑紧急的)
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
在某游戏平台打折之际,EternityEternityEternity兴致勃勃地在该游戏平台上购买了nnn个不同的游戏,从1到nnn编号。
通过游览游戏论坛EternityEternityEternity确定了完成每个游戏的准确时间并在这nnn个游戏中找到了mmm个特别喜欢的游戏,这些游戏有个共同的特点,那就是都和火焰元素、雪元素相关!这让EternityEternityEternity爱不释手,这意味着EternityEternityEternity将必须去完成这mmm个游戏。
但是当EternityEternityEternity准备玩游戏时,EternityEternityEternity发现快要期末考试了,EternityEternityEternity需要忙着期末复习,但是EntityEntityEntity又经受不住游戏的诱惑,所以EternityEternityEternity决定抽出部分时间去玩至少kkk个游戏。但是EternityEternityEternity忙于玩游戏,所以请你求出EternityEternityEternity最少的游戏时间。
输入描述:
第一行输入三个整数n,m,k(1≤n≤103,0≤m≤k≤n)n,m,k(1 \le n \le 10^3, 0 \le m \le k \le n)n,m,k(1≤n≤103,0≤m≤k≤n),nnn代表EternityEternityEternity购买的总共的游戏数量,mmm代表nnn个游戏中EternityEternityEternity喜欢的游戏数量,kkk代表EternityEternityEternity至少要玩的游戏数量。 第二行包含nnn个整数a1,a2,...,an(1≤ai≤105)a_1,a_2,...,a_n(1 \le a_i \le 10^5)a1,a2,...,an(1≤ai≤105),aia_iai代表完成第iii个游戏所需要的时间。 第三行包含mmm个整数b1,b2,...,bm(1≤bi≤n,保证bi各不相同)b_1,b_2,...,b_m(1 \leq b_i \leq n,保证b_i各不相同)b1,b2,...,bm(1≤bi≤n,保证bi各不相同),bib_ibi代表EternityEternityEternity特别喜欢的游戏编号。
输出描述:
输出一行一个整数代表EternityEternityEternity最少的游戏时间。
示例1
输入
复制5 2 3 1 2 3 4 5 2 4
5 2 3 1 2 3 4 5 2 4
输出
复制7
7
说明
EternityEternityEternity很喜欢编号为2,4的游戏,他会花费2+4 = 6的时间先完成这两个游戏,完成这两个游戏过后,kkk - 2 = 1,所以只需要完成编号为1的游戏就能到达至少kkk个游戏的目标,所以总共花的时间为6 + 1 = 7。
思路:其实一开始想用map<int ,int>来着,把编号和时间考虑进去,后来发现是一道大水题
呵呵
亮点:呵呵
#include <bits/stdc++.h> using namespace std; int n,m,k; int ans; //含有两个信息:时间和编号 struct node{ int vis; int time; }yx[2000]; bool cmp(node &a,node &b){ return a.time<b.time; } int main(){ cin>>n>>m>>k; for(int i=1;i<=n;i++){ cin>>yx[i].time; yx[i].vis=1; } for(int i=1;i<=m;i++){ int t; cin>>t; ans+=yx[t].time; yx[t].vis=0; } int cent=0; sort(yx+1,yx+n+1,cmp); for(int i=1;i<=n;i++){ if(yx[i].vis){ if(cent<k-m){ ans+=yx[i].time; cent++; } } } cout<<ans<<endl; }
那道题有种倒推的思想
#include <bits/stdc++.h> using namespace std; priority_queue<int> s; int n; struct Node{ int t,d; }ti[150010]; bool cmp(Node a,Node b){ return a.d<b.d; } int main(){ int sum=0; cin>>n; for(int i=1;i<=n;i++) cin>>ti[i].t>>ti[i].d; sort(ti+1,ti+1+n,cmp); for(int i=1;i<=n;i++){ sum+=ti[i].t; s.push(ti[i].t); while(sum>ti[i].d){ sum-=s.top(); s.pop(); } } cout<<s.size()<<endl; return 0; } ———————————————— 版权声明:本文为CSDN博主「防秃头少女」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_61546598/article/details/122147999
可恶:
想不出来了这个矩阵快速幂做的着实拉跨
为什么
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
定义
f(x)={0x=01x=12x=23x=3f(x−1)+f(x−3)x>3f(x)= \begin{cases} 0 & x=0\\ 1 & x=1\\ 2 & x=2\\ 3 & x=3\\ f(x-1)+f(x-3) & x>3 \end{cases}f(x)=⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧0123f(x−1)+f(x−3)x=0x=1x=2x=3x>3
给定xxx,求出 f(x)f(x)f(x)
输入描述:
一行,一个数x,(0≤x≤107)x, (0 \le x \le 10^7)x,(0≤x≤107)
输出描述:
由于最后答案可能很大,请输出将答案对109+710^9+7109+7 取模的结果
示例1
输入
复制9
9
输出
复制28
28
说明
前十项的函数值分别为:0,1,2,3,4,6,9,13,19,28,所以 f(9)f(9)f(9) = 28。
//这个东西明显和斐波那契额数列一样
//递推关系为f(n)=f(n-1)+f(n-3)
//数据量大时用矩阵快速幂呀T=10^4,n<=10^18
#include<bits/stdc++.h>
using namespace std;
const int MOD= 1e9+7;
struct Matrix{
long long a[4][4];
Matrix(){memset(a,0,sizeof(a));}
void setE(int x){
for(int i=1;i<=3;i++){
a[i][i]=x;
}
}
};
Matrix operator*(const Matrix &a,const Matrix &b){
Matrix res;
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
for(int k=1;k<=3;k++){
res.a[i][j]=(res.a[i][j]+a.a[i][k]*b.a[k][j])%MOD;
}
}
}
return res;
}
Matrix qpow(Matrix m, long long n){
Matrix ans;
ans.setE(1);
while(n>0){
if(n&1)ans=ans*m;
m=m*m;
n>>=1;
}
return ans;
}
void solve(){
Matrix trans,f;
trans.a[1][1]=trans.a[3][1]=trans.a[1][2]=trans.a[2][3]=1;
f.a[1][1]=4;
f.a[2][1]=3;
f.a[3][1]=2;
long long n;
scanf("%lld",&n);
trans=qpow(trans,n-4);
trans=trans*f;
printf("%lld\n",trans.a[1][1]%MOD);
}
int main(){
solve();
return 0;
}
我就是摆烂之王