2024-3-30 网易雷火笔试题题解(A~C)
一小时写了A~C 剩下两小时没调出D的 最后D还是0分
A
题目描述
网易在从两年前开始对司龄1,3,6,10年的员工发纪念积木,今年决定补发以前没有补发的积木,问还各个类型的积木需要多少个
输入描述:
第一行输入一个N (1<=N<=10000),表示雷火的员工数量。
接下来一行是N个整数(1<=司龄<=20),表示每个员工今年达到的司龄。
思路:
暴力特判前两年有没有发过那几个奖品
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) int cnt[4]; int main(void) { int n; scanf("%d",&n); _for(i,1,n) { int x; scanf("%d",&x); if(x>=1) cnt[0]++; if(x>=3) cnt[1]++; if(x>=6) cnt[2]++; if(x>=10) cnt[3]++; if(x-1==1) cnt[0]--; if(x-1==3) cnt[1]--; if(x-1==6) cnt[2]--; if(x-1==10) cnt[3]--; if(x-2==1) cnt[0]--; if(x-2==3) cnt[1]--; if(x-2==6) cnt[2]--; if(x-2==10) cnt[3]--; } _for(i,0,3) printf("%d ",cnt[i]); }
B:(O(NlogN)解法)
题目描述:
初始有一个长度为1的文本,我们可以采用Ctrl A全选文本,Ctrl S选中单个文本,Ctrl C复制文本,Ctrl V粘贴文本,问给n个k,对于每个k得到一个长度为k的文本至少需要多少次。
思路:
当我们得到一个长度为x的串后,我们可以通过该串全选一次,复制一次,然后粘贴若干次后,去更新其他值(该部分时间复杂度与欧拉常数有关,总体复杂度为O(nlogn)),也可以通过该数字,选中单个文本一次,复制一次,粘贴若干次,去更新其他值(由于更新条件是dp[r]-dp[l]>r-l+2,因此可以构造val[x]=dp[x]-x,因此,我们可以维护val[x]的最小值mn,当val[i]>mn+2时,我们可以将dp[i]更新为mn+2+i,由于对于数组每个元素,可以O(1)求解,该部分的时间复杂度为O(n))。综上,总体复杂度为O(n),(复杂度中与n表示数据范围)
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) const int lim=16384; int dp[lim]; int val[lim]; inline void funct() { memset(dp,1,sizeof(dp)); dp[1]=0; int mn=1000000000; for(int i=1;i<lim;i++) { dp[i]=min(dp[i],mn+2+i); val[i]=dp[i]-i; mn=min(val[i],mn); for(int j=i+i,cnt=3;j<lim;j+=i,++cnt) { dp[j]=min(dp[i]+cnt,dp[j]); } } } int main(void) { int T; scanf("%d",&T); funct(); // _for(i,1,16) printf("%d: %d\n",i,dp[i]); while(T--) { int x; scanf("%d",&x); printf("%d\n",dp[x]); } }
C
题目简述:
有一个战斗力为p的玩家,以及一个n个怪物(怪物按战斗力正序输入),m个BOSS,可以耗费1cost,击败一个战斗力小于自己的非BOSS怪物,然后获得该怪物的战斗力,也可以耗费1cost,使得自己的战斗加上p/10,问,对于每个BOSS,如果需要击败该BOSS,需要消耗几cost
思路:
将能打过的所有怪物存入优先队列中,每次战斗力更新后,是否有新增可打败怪物,倘若有则更新可以战胜怪物列表。给BOSS存入优先队列(小根堆)中,当队列顶的BOSS不能打败时,考虑如何提升战斗力,为了使提升的战斗力最大化,我们可以看可战胜怪物中战斗力最高的怪物与p/10谁大,去决定打怪物还是让自己战斗加上p/10。直到所有BOSS的结果都计算出为止
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; #define _for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define MAXN 100050 int monster[MAXN]; int ans[MAXN]; class node { public: int request,id,ans; node(int _request,int _id) { request=_request; id=_id; ans=0; } bool operator <(const node& b)const& { return b.request<request; } }; priority_queue<node> BOSS_queue; priority_queue<int> monster_queue; int p,n,m; inline void update_monster_queue(int &place,int x) { for(place;place<=n&&monster[place]<x;place++) { monster_queue.push(monster[place]); } } int main(void) { scanf("%d%d%d",&p,&n,&m); _for(i,1,n) { scanf("%d",&monster[i]); } _for(i,1,m) { int x; scanf("%d",&x); BOSS_queue.push(node(x+1,i)); } int place=1; int cnt=0; update_monster_queue(place,p); while(!BOSS_queue.empty()) { node now_BOSS=BOSS_queue.top(); printf("%d %d\n",now_BOSS.id,now_BOSS.request); while(p<now_BOSS.request) { ++cnt; if(!monster_queue.empty()&&monster_queue.top()>p/10) { p+=monster_queue.top(); monster_queue.pop(); } else { p+=p/10; } update_monster_queue(place,p); } ans[now_BOSS.id]=cnt; BOSS_queue.pop(); } _for(i,1,m) { printf("%d\n",ans[i]); } }