我是靠谱客的博主 激情砖头,这篇文章主要介绍2022/4/30,现在分享给大家,希望可以做个参考。

Sage's Birthday (hard version)

还以为这个难得版本得有多难呢,直接按照常规思路来就可以,n个数最多能有(n-1)/2个cheap,然后将a数组分成两个数组,一个b数组存前(n-1)/2个最小值,一个c数组存剩下的数,然后用二分将最小值不断地插入到c中统计次数输出就行;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h> #define ll long long using namespace std; const ll inf=1e18; const ll mod=1e9+7; ll n,a[100005],b[100005],c[100005],vis[100005]; int main(){ //freopen("in.txt","r",stdin); scanf("%lld",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+n+1); if(n==1||n==2){ printf("0n"); for(int i=1;i<=n;i++) printf("%lld ",a[i]); return 0; } ll ans=0,bb=0,cc=0,bou=1; for(int i=1;i<=(n-1)/2;i++) b[++bb]=a[i]; for(int i=(n-1)/2+1;i<=n;i++) c[++cc]=a[i]; for(int i=1;i<=bb;i++){ ll id=upper_bound(c+bou,c+cc+1,b[i])-c; if(id+1<=cc&&!vis[id]){ vis[id]=b[i]; ans++; bou=id+1; } else{ vis[bou++]=b[i]; } } printf("%lldn",ans); for(int i=1;i<=cc;i++){ printf("%lld ",c[i]); if(vis[i]) printf("%lld ",vis[i]); } ll x=n+1; while(vis[x]!=0) printf("%lld ",vis[x]),x++;//这句话貌似没用 return 0; }

Constructing the Array

看了得半小时,发现没有啥规律,只能去看一下标签提示,有数据结构就突然想到了优先队列,不得不说优先队列真是个好东西,用优先队列去模拟这个情况就可以了;

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<bits/stdc++.h> #define ll long long using namespace std; const ll inf=1e18; const ll mod=1e9+7; ll t,n,ans[200005]; struct node{ ll l,r; bool operator<(const node &a)const{ if(a.r-a.l==r-l) return a.r<r; return a.r-a.l>r-l; } }; int main(){ //freopen("in.txt","r",stdin); scanf("%lld",&t); while(t--){ scanf("%lld",&n); for(int i=1;i<=n;i++) ans[i]=0; priority_queue<node>q; q.push(node{1,n}); ll cnt=1; while(!q.empty()){ node u=q.top();q.pop(); if((u.r-u.l+1)&1){ ans[(u.r+u.l)/2]=cnt; if((u.l+u.r)/2-1>=u.l) q.push(node{u.l,(u.r+u.l)/2-1}); if((u.l+u.r)/2+1<=u.r) q.push(node{(u.r+u.l)/2+1,u.r}); } else{ ans[(u.l+u.r-1)/2]=cnt; if((u.l+u.r-1)/2-1>=u.l) q.push(node{u.l,(u.l+u.r-1)/2-1}); if((u.l+u.r-1)/2+1<=u.r) q.push(node{(u.l+u.r-1)/2+1,u.r}); } cnt++; } for(int i=1;i<=n;i++) printf("%lld ",ans[i]); printf("n"); } return 0; }

L-Spicy Restaurant_2021 年第十三届四川省 ACM-ICPC 大学生程序设计竞赛(重现赛)(重现赛) (nowcoder.com)

多源bfs,w的值只有100,所以可以暴力预处理出i点到辣味j的最短距离,dis[j][i]表示i点到辣味j的最短距离,多源bfs跑一下,然后再正着转移一遍,之后判断;

(11条消息) The 2021 Sichuan Provincial 四川省赛 L. Spicy Restaurant(多源bfs)_issue是fw的博客-CSDN博客

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<bits/stdc++.h> #define ll long long using namespace std; const ll mod=1e9+7; int cnt,head[200005],dis[110][100005],inf; int n,m,q,w[100005]; struct Edge{ int to,dis,next; }edge[200005]; void addedge(int from,int to){ edge[++cnt].to=to; edge[cnt].next=head[from]; head[from]=cnt; } void bfs(int sp){ queue<int>q; for(int i=1;i<=n;i++) if(w[i]==sp){ q.push(i); dis[sp][i]=0; } while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];i;i=edge[i].next){ int j=edge[i].to; if(dis[sp][j]!=inf) continue;//这地方其实和vis数组的作用一样,但这样省的另开一个了 //做法也挺巧妙的,也省去了一些思考复杂度 dis[sp][j]=dis[sp][u]+1; q.push(j); } } } int main(){ //freopen("in.txt","r",stdin); scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } memset(dis,0x3f,sizeof(dis)); inf=dis[0][0]; for(int i=100;i>=1;i--) bfs(i); for(int i=1;i<=n;i++) for(int j=1;j<=100;j++) dis[j][i]=min(dis[j][i],dis[j-1][i]); while(q--){ int l,r; scanf("%d%d",&l,&r); if(dis[r][l]==inf) printf("-1n"); else printf("%dn",dis[r][l]); } return 0; }

P1083 [NOIP2012 提高组] 借教室 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

用差分数组去维护前x天的增量,再反推回前x天每天需要多少教室,然后去判断,这个x要去二分得到,为什么可以用二分呢,二分能使用的条件是单调递增或者是局部舍弃性,如果我们第i天满足不了,那后面的也一定满足不了,如果第i天满足了,那么前i-1天也一定能满足,这就符合局部舍弃性,所以可以二分;

 2012 D2 T2 借教室 题解 - 笨蛋花的小窝qwq - 洛谷博客

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<bits/stdc++.h> #define ll long long using namespace std; const ll inf=1e18; const ll mod=1e9+7; ll n,m,r[1000006],b[1000006],d[1000006],s[1000006],t[1000006],need[1000006]; bool check(ll x){ memset(b,0,sizeof(b)); for(int i=1;i<=x;i++){ b[s[i]]+=d[i]; b[t[i]+1]-=d[i]; } for(int i=1;i<=n;i++){ need[i]=need[i-1]+b[i]; if(need[i]>r[i]) return 0; } return 1; } int main(){ //freopen("in.txt","r",stdin); scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&r[i]); for(int i=1;i<=m;i++) scanf("%lld%lld%lld",&d[i],&s[i],&t[i]); if(check(m)){ printf("0n"); return 0; } ll l=1,r=m,ans=inf; while(l<=r){ ll mid=l+r>>1; if(!check(mid)) ans=min(mid,ans),r=mid-1; else l=mid+1; } printf("-1n%lld",ans); return 0; }

最后

以上就是激情砖头最近收集整理的关于2022/4/30的全部内容,更多相关2022/4/30内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部