NOI Online #2 入门组

未了#

题意:

一座高n米的山,每秒爬v米,有n个魔法,第i个魔法可以让你爬到ai米时传送回山脚,m次询问,每次问最少用多少个魔法,才能让爬山时间大于ti

n,m105

题解:

ai从大到小排序,前缀和二分。O(nlogn)

Copy
#include<bits/stdc++.h> using namespace std; namespace red{ #define int long long #define ls(p) (p<<1) #define rs(p) (p<<1|1) #define mid ((l+r)>>1) #define lowbit(i) ((i)&(-i)) const int N=3e5+10; int n,m,len,v; int a[N],s[N]; inline void main() { ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); int n,len,v; cin>>n>>len>>v; for(int i=1;i<=n;++i) cin>>a[i]; sort(a+1,a+n+1); for(int i=1;i<=n;++i) s[i]=s[i-1]+a[n-i+1]; cin>>m; for(int i=1;i<=m;++i) { int x;cin>>x; x=x*v; x-=len; if(x>=s[n]) cout<<"-1\n"; else { int t=upper_bound(s+0,s+n+1,x)-s; cout<<t<<'\n'; } } } } signed main() { red::main(); return 0; }

荆轲刺秦王#

题意:

nm的地图上荆轲要去刺秦王,荆轲每秒可以向周围八个格子移动一步,地图上有卫兵,可以发现曼哈顿距离小于ai,j范围内的格子的入侵者。

荆轲可以用技能:

1.隐身,一秒内不被卫兵发现

2.瞬移,朝上下左右某个方向移动d

分别能用c1,c2

问荆轲最短几步内能刺杀秦王,步数最短的情况下,使用两种技能总次数最少,前面的前提下,隐身次数最少。

n,m,d,ai,j350,c1,c215

题解:

用差分处理曼哈顿距离,预处理出哪些格子必须隐身才能走过去。

然后就是裸bfs

O(nm2+nmc1c2)

Copy
#include<bits/stdc++.h> using namespace std; namespace red{ #define int long long #define ls(p) (p<<1) #define rs(p) (p<<1|1) #define mid ((l+r)>>1) #define lowbit(i) ((i)&(-i)) const int N=350+10,inf=2e9; int a[N][N],cf[N][N]; int n,m,c1,c2,d; int stx,sty,edx,edy; struct node { int x,y,s1,s2,dis; }; queue<node> q; bool vis[355][355][16][16]; int dx[8]={-1,-1,0,1,1,1,0,-1},dy[8]={0,1,1,1,0,-1,-1,-1}; int ans1,ans2,ans3; inline void bfs() { q.push((node){stx,sty,0,0,0}); ans1=inf; while(!q.empty()) { node now=q.front(); q.pop(); int x=now.x,y=now.y,s1=now.s1,s2=now.s2,dis=now.dis; //cout<<x<<' '<<y<<' '<<dis<<endl; if(vis[x][y][s1][s2]) continue; vis[x][y][s1][s2]=1; if(x==edx&&y==edy) { if(dis<ans1||(dis==ans1&&s1+s2<ans2+ans3)||(dis==ans1&&s1+s2==ans2+ans3&&s1<ans2)) ans1=dis,ans2=s1,ans3=s2; } if(dis>ans1) break; for(int k=0;k<8;++k) { int tx=x+dx[k],ty=y+dy[k],ts1=s1,ts2=s2,tdis=dis+1; //cout<<tx<<' '<<ty<<"!!"<<endl; if(a[tx][ty]==-1||tx<1||tx>n||ty<1||ty>m) continue; ts1+=a[tx][ty]; if(ts1>c1||ts2>c2) continue; if(vis[tx][ty][ts1][ts2]) continue; q.push((node){tx,ty,ts1,ts2,tdis}); } for(int k=0;k<8;k+=2) { int tx=x+dx[k]*d,ty=y+dy[k]*d,ts1=s1,ts2=s2+1,tdis=dis+1; if(a[tx][ty]==-1||tx<1||tx>n||ty<1||ty>m) continue; ts1+=a[tx][ty]; if(ts1>c1||ts2>c2) continue; if(vis[tx][ty][ts1][ts2]) continue; q.push((node){tx,ty,ts1,ts2,tdis}); } } if(ans1==inf) cout<<"-1\n"; else cout<<ans1<<' '<<ans2<<' '<<ans3<<'\n'; } inline void main() { ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); cin>>n>>m>>c1>>c2>>d; for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { string ch;cin>>ch; if(ch[0]=='S') stx=i,sty=j; if(ch[0]=='T') edx=i,edy=j; if(ch[0]>='0'&&ch[0]<='9') { int num=0; for(int k=0;k<ch.length();++k) num=num*10+ch[k]-'0'; --num; a[i][j]=-1; for(int k=i-num,l=0;k<=i;++k,++l) { if(k>=1) { ++cf[k][max(1ll,j-l)]; if(j+l+1<=m) --cf[k][j+l+1]; } } for(int k=i+1,l=num-1;k<=min(n,i+num);++k,--l) { ++cf[k][max(1ll,j-l)]; if(j+l+1<=m) --cf[k][j+l+1]; } } } } for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { cf[i][j]+=cf[i][j-1]; if(cf[i][j]>0&&!a[i][j]) a[i][j]=1; //cout<<a[i][j]<<" \n"[j==m]; } } bfs(); } } signed main() { red::main(); return 0; }

建设城市#

题意:

2n栋楼,每栋楼高是1m,要求前n栋楼高度不下降,后n栋楼高度不上升,且编号为x,y的楼高度相等,求方案数。

n,m105

xn,y>n为例:

枚举x,y的高度k

ans=k=1mf(x1,k)f(nx,mk+1)f(yn1,mk+1)f(2ny,k)

其中f(n,m)表示n栋楼,取值范围是1m,且不下降的方案数。

这个方案数其实就是n个物品分成m组,可以有空组的方案数。

O(2n+m)

Copy
#include<bits/stdc++.h> using namespace std; namespace red{ #define int long long #define ls(p) (p<<1) #define rs(p) (p<<1|1) #define mid ((l+r)>>1) #define lowbit(i) ((i)&(-i)) const int N=5e5+10,mod=998244353,inf=2e9; int n,m,x,y; int fac[N],inv[N]; inline int fast(int x,int k) { int ret=1; while(k) { if(k&1) ret=ret*x%mod; x=x*x%mod; k>>=1; } return ret; } inline int C(int n,int m) { if(n<m) return 0; return fac[n]*inv[m]%mod*inv[n-m]%mod; } inline int cb(int n,int m) { //cout<<n<<' '<<m<<' '<<C(n+m-1,m-1)<<"!!"<<endl; //x1+x2+…+xm=n // return C(n+m-1,m-1); } inline void work1() { int ans=0; for(int k=1;k<=m;++k) { int tmp=cb(x-1,k)*cb(n-y,m-k+1)%mod*cb(n,m)%mod; ans=(ans+tmp)%mod; } cout<<ans<<'\n'; } inline void work2() { int ans=0; for(int k=1;k<=m;++k) { int tmp=cb(x-1,k)*cb(n-x,m-k+1)%mod*cb(2*n-y,k)%mod*cb(y-n-1,m-k+1)%mod; //cout<<k<<' '<<cb(x-1,k)<<' '<<cb(n-x,m-k+1)<<' '<<cb(y-n-1,m-k+1)<<' '<<cb(2*n-y,k)<<endl; ans=(ans+tmp)%mod; } cout<<ans<<'\n'; } inline void init(int n) { fac[0]=inv[0]=1; for(int i=1;i<=n;++i) fac[i]=fac[i-1]*i%mod; inv[n]=fast(fac[n],mod-2); for(int i=n-1;i>=1;--i) inv[i]=inv[i+1]*(i+1)%mod; } inline void main() { ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); cin>>m>>n>>x>>y; init(2*n+m); if(x>y) swap(x,y); if(x>n) { x=2*n-x+1,y=2*n-y+1; swap(x,y); } if(y<=n) work1(); else work2(); } } signed main() { red::main(); return 0; } /* 3 2 3 4 */
posted @   lovelyred  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示
CONTENTS