我是靠谱客的博主 激情砖头,最近开发中收集的这篇文章主要介绍2022/4/30,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Sage's Birthday (hard version)

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

#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

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

#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博客

#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 - 洛谷博客

#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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部