Codeforces Round #661 (Div. 3)

A - Remove Smallest

排个序,如果相邻的数大于一就不满足题意

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=110;
int a[N];
int main()
{IO;int T;cin>>T;while(T--){int n;cin>>n;for(int i=0;i<n;i++) cin>>a[i];sort(a,a+n);bool ok=1;for(int i=0;i<n-1;i++)if(a[i+1]>a[i]+1) {ok=0;break;}if(ok) cout<<"YES"<<endl;else cout<<"NO"<<endl;}return 0;
}

B - Gifts Fixing

礼物最终个数肯定是最小的那个。每个礼物减小到最少的那个,注意可以同时减少两种礼物。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=110;
ll a[N],b[N];
int main()
{IO;int T;cin>>T;while(T--){int n;cin>>n;ll mina=2e9;ll minb=2e9;for(int i=0;i<n;i++) {cin>>a[i];mina=min(mina,a[i]);}for(int i=0;i<n;i++){cin>>b[i];minb=min(minb,b[i]);}ll res=0;for(int i=0;i<n;i++) res+=max(a[i]-mina,b[i]-minb);cout<<res<<endl;}return 0;
}

C - Boats Competition

枚举+双指针
由于体重非常小,两两配对的体重和也很小,直接暴力枚举两两体重和w。现在问题转化成原序列找出两个数的和等于w,双指针。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=110;
int a[N],n;
int main()
{IO;int T;cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];if(n==1) {cout<<0<<endl;continue;}sort(a+1,a+n+1);int res=0,mx=0;for(int w=a[1]+a[2];w<=a[n-1]+a[n];w++){int cnt=0;for(int i=1,j=n;i<j;i++){while(j>i&&a[i]+a[j]>w) j--;if(j<=i) break; //注意这点 因为这wa了一次if(a[i]+a[j]==w) cnt++,j--;}res=max(res,cnt);}cout<<res<<endl;}return 0;
}

D - Binary String To Subsequences

贪心+二分
贪心:如果该位是1那么找一个末尾是0的序列放进去如果不存在那么新添一组
比如目前有五组0 0 1 1 1分别表示该组最后一个字符是0或者1,如果该位是1我们就二分出最后一个0,pos=2,组别表示变成0 1 1 1 1。如果该位使0我们二分处第一个1的位置,pos=3,组别表示变成0 0 0 1 1,这样操作可以发现组别表示的序列始终是有序的,保证时间复杂度为O(nlogn)O(nlogn)O(nlogn)
好像有O(n)O(n)O(n)的做法奈何wctl,写题的时候只想到这个做法。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
const int N=200010;
int pos[N],a[N];
int main()
{IO;int T;cin>>T;while(T--){int n;string s;cin>>n>>s;int cnt=1;a[1]=s[0]-'0';pos[0]=1;for(int i=1;i<n;i++){int t=s[i]-'0';if(t){int l=1,r=cnt;while(l<r){int mid=l+r+1>>1;if(a[mid]<=0) l=mid;else r=mid-1;}if(a[l]==0){a[l]=1;pos[i]=l;}else {a[++cnt]=1;pos[i]=cnt;}}else{int l=1,r=cnt;while(l<r){int mid=l+r>>1;if(a[mid]>=1) r=mid;else l=mid+1;}if(a[l]==1){a[l]=0;pos[i]=l;}else {a[++cnt]=0;pos[i]=cnt;}}}cout<<cnt<<endl;for(int i=0;i<n;i++) cout<<pos[i]<<" ";cout<<endl;}return 0;
}

这次做了4个题,差一点做出了E1。

E1 - Weights Division (easy version)

我没想到这次我不在意的点就是这题的关键的!!!
先dfs一下把从根节点到每个叶子节点每条边跑的次数记录一下,记作cnt[i],如果该边边权为w[i]如果把这条边砍一半,那么总的路程减小(w[i]-w[i]/2)*cnt[i],显然贪心,用个优先队列(按照减小的多优先级高)维护一下就行了。
坑点:很容易想到按照w[i]*cnt[i]排序,不过这题下取整导致问题不断。(我做的时候想这题应该不会那么麻烦,就图个省事结果。。。)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N=100010,M=400010;
int h[N],e[M],ne[M],idx;
ll w[M],limit,res;
int n,d[N],cnt[M];
struct node
{ll w;int num;bool operator <(const node&o)const{ll sub1=(w-w/2)*num;ll sub2=(o.w-o.w/2)*o.num;return sub1<sub2;//其实也可以直接 return (w+1)/2*num<(o.w+1)/2*o.num; 上去整}
};
priority_queue<node> q;void add(int a,int b,ll c)
{e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;d[b]++;//统计度数,度数为1是叶子节点
}
int dfs(int u,int fa)
{int lcnt=0;for(int i=h[u];i!=-1;i=ne[i]){int j=e[i];if(j==fa) continue;cnt[i]+=(d[j]==1);cnt[i]+=dfs(j,u);lcnt+=cnt[i];}return lcnt;
}
void init()
{for(int i=0;i<=n;i++) h[i]=-1,d[i]=0,cnt[i]=0,cnt[i+n]=0;idx=res=0;while(q.size()) q.pop();
}
int main()
{IO;int T;cin>>T;while(T--){cin>>n>>limit;init();for(int i=1;i<n;i++){int a,b;ll c;cin>>a>>b>>c;add(a,b,c);add(b,a,c);}dfs(1,-1);for(int i=0;i<2*n-2;i+=2) {q.push({w[i],cnt[i]+cnt[i+1]});res+=w[i]*(cnt[i]+cnt[i+1]);}ll ans=0;while(res>limit){auto t=q.top();q.pop();q.push({t.w/2,t.num});res-=1ll*(t.w-t.w/2)*t.num;ans++;}cout<<ans<<endl;}return 0;
}

E2 - Weights Division (hard version)

E1砍边都是花费1代价,而E2就是有些边砍一半需要花费1代价有些2代价。显然我们考虑用两个优先队列维护q1,q2q1维护花费1代价的 q2维护花费2代价的。仍然贪心。每次考虑花费1代价砍边,如果发现花两次1代价减小的路程小于直接花费2代价砍边减小的路程,那么就直接花费2代价砍边。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N=100010,M=200010;
int h[N],e[M],ne[M],idx,cost[M];
ll w[M],limit,res;
int n,d[N],cnt[M];
struct node
{ll w;int num;bool operator <(const node&o)const{ll sub1=(w-w/2)*num;ll sub2=(o.w-o.w/2)*o.num;return sub1<sub2;}
};
priority_queue<node> q1,q2;
void add(int a,int b,ll c,int coin)
{e[idx]=b;w[idx]=c;cost[idx]=coin;ne[idx]=h[a];h[a]=idx++;d[b]++;
}
int dfs(int u,int fa)
{int lcnt=0;for(int i=h[u];i!=-1;i=ne[i]){int j=e[i];if(j==fa) continue;cnt[i]+=(d[j]==1);cnt[i]+=dfs(j,u);lcnt+=cnt[i];}return lcnt;
}
void init()
{for(int i=0;i<=n;i++) h[i]=-1,d[i]=0,cnt[i]=0,cnt[i+n]=0;idx=res=0;while(q1.size()) q1.pop();while(q2.size()) q2.pop();q1.push({0,0}),q1.push({0,0}),q2.push({0,0});//哨兵,避免很多边界情况。
}
int main()
{IO;int T;cin>>T;while(T--){cin>>n>>limit;init();for(int i=1;i<n;i++){int a,b,coin;ll c;cin>>a>>b>>c>>coin;add(a,b,c,coin);add(b,a,c,coin);}dfs(1,-1);for(int i=0;i<2*n-2;i+=2) {if(cost[i]==1) q1.push({w[i],cnt[i]+cnt[i+1]});else q2.push({w[i],cnt[i]+cnt[i+1]});res+=w[i]*(cnt[i]+cnt[i+1]);}ll ans=0;while(res>limit){auto a=q1.top();q1.pop();auto b=q1.top();q1.pop();auto c=q2.top();q2.pop();ll suba=(a.w-a.w/2)*a.num;ll subb=max((a.w/2-a.w/4)*a.num,(b.w-b.w/2)*b.num);ll subc=(c.w-c.w/2)*c.num;if(res-suba<=limit) {ans++;break;}else {if(suba+subb<=subc){res-=subc;q1.push(a),q1.push(b);q2.push({c.w/2,c.num});ans+=2;}else{res-=suba;q1.push(b),q1.push({a.w/2,a.num});q2.push(c);ans++;}}}cout<<ans<<endl;}return 0;
}

注意:每次只考虑花费1代价砍边
我在写的时候写了一份每次考虑花费2代价砍边。比较两次1代价和一次2代价减小的路程吗,这样贪心其实不正确,非常dt。
下面代码是错误的贪心思路每次考虑花费2代价砍边

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#define debug(x) cout<<#x<<": "<<x<<" "
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N=100010,M=400010;
int h[N],e[M],ne[M],idx,cost[M];
ll w[M],limit,res;
int n,d[N],cnt[M];
struct node
{ll w;int num;bool operator <(const node&o)const{ll sub1=(w-w/2)*num;ll sub2=(o.w-o.w/2)*o.num;return sub1<sub2;}
};
priority_queue<node> q1,q2;void add(int a,int b,ll c,int coin)
{e[idx]=b;w[idx]=c;cost[idx]=coin;ne[idx]=h[a];h[a]=idx++;d[b]++;
}
int dfs(int u,int fa)
{int lcnt=0;for(int i=h[u];i!=-1;i=ne[i]){int j=e[i];if(j==fa) continue;cnt[i]+=(d[j]==1);cnt[i]+=dfs(j,u);lcnt+=cnt[i];}return lcnt;
}
void init()
{for(int i=0;i<=n;i++) h[i]=-1,d[i]=0,cnt[i]=0,cnt[i+n]=0;idx=res=0;while(q1.size()) q1.pop();while(q2.size()) q2.pop();
}
int main()
{IO;int T;cin>>T;while(T--){cin>>n>>limit;init();for(int i=1;i<n;i++){int a,b,coin;ll c;cin>>a>>b>>c>>coin;add(a,b,c,coin);add(b,a,c,coin);}dfs(1,-1);for(int i=0;i<2*n-2;i+=2) {if(cost[i]==1) q1.push({w[i],cnt[i]+cnt[i+1]});else q2.push({w[i],cnt[i]+cnt[i+1]});res+=w[i]*(cnt[i]+cnt[i+1]);}q1.push({0,0}),q1.push({0,0}),q2.push({0,0});ll ans=0;while(res>limit){auto a=q1.top();q1.pop();auto b=q1.top();q1.pop();auto c=q2.top();q2.pop();ll suba1=(a.w-a.w/2)*a.num;ll suba2=(a.w/2-a.w/4)*a.num;ll subb=(b.w-b.w/2)*b.num;ll subc=(c.w-c.w/2)*c.num;if(res-suba1<=limit) {ans++;break;}else if(res-suba1-max(suba2,subb)<=limit||res-subc<=limit) {ans+=2;break;}else if(res-suba1-subc<=limit) {ans+=3;break;}else {if(suba2>subb){if(suba1+suba2>subc){res-=suba1+suba2;q1.push(b),q1.push({a.w/4,a.num});q2.push(c);}else{res-=subc;q1.push(a),q1.push(b);q2.push({c.w/2,c.num});}}else{if(suba1+subb>subc){res-=suba1+subb;q1.push({b.w/2,b.num}),q1.push({a.w/2,a.num});q2.push(c);}else{res-=subc;q1.push(a),q1.push(b);q2.push({c.w/2,c.num});}}ans+=2;}}cout<<ans<<endl;}return 0;
}

嘻嘻还是div3能上一点分QvQ,希望今天div2掉少点分(div2日常掉分)-。-,要加油哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7 lldb 调试netcore应用的内存泄漏和死循环示例(dump文件调试)

写个demo来玩一玩linux平台下使用lldb加载sos来调试netcore应用。当然&#xff0c;在真实的产线环境中需要分析的数据和难度远远高于demo所示&#xff0c;所以demo的作用也仅仅只能起到介绍工具的作用。通常正常情况下&#xff0c;分析个几天才能得出一个结论的的结果都还是比较…

P4450-双亲数,P5221-Product,P6055-[RC-02]GCD【莫比乌斯反演,杜教筛】

除了最后一题都比较简单就写一起了 P4450-双亲数 题目链接:https://www.luogu.com.cn/problem/P4450 题目大意 给出A,B,dA,B,dA,B,d求有多少对(a,b)(a,b)(a,b)满足gcd(a,b)dgcd(a,b)dgcd(a,b)d且a∈[1,A],b∈[1,B]a\in[1,A],b\in[1,B]a∈[1,A],b∈[1,B] 解题思路 很显然的…

【Trie】最大异或对(ybtoj Trie-2)

正题 ybtoj Trie-2 题目大意 给你n个数&#xff0c;选择2个&#xff0c;使其异或值最大 解题思路 对于每个数的二进制建立Trie&#xff0c;然后每个数在Trie中搜索&#xff0c;每次尽量走不同方向 代码 #include<cstdio> #include<cstring> #include<iostrea…

[SCOI2003]字符串折叠

[SCOI2003]字符串折叠 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 折叠的定义如下&#xff1a; 一个字符串可以看成它自身的折叠。记作S S X(S)是X(X>1)个S连接在一…

Codeforces Round #662 (Div. 2)

就写了两个题&#xff0c;以为要掉分&#xff0c;结果早上起来发现还上分了&#xff08;说明wtcl A - Rainbow Dash, Fluttershy and Chess Coloring 无论边长是奇数还是偶数&#xff0c;考虑每次操作最外层的一圈&#xff0c;一个人操作一圈的一般&#xff0c;然后另一个人就…

.NET微服务方案调查

.NET Core就是专门针对模块化的微服务架构而设计&#xff0c;调查下大家选择.NET微服务情况&#xff0c;如果你有微服务方面的需求可以找我哦&#xff0c;可加我微信geffzhang&#xff1a;相关文章&#xff1a;Service Fabric 与Ocelot 的集成Ocelot简易教程&#xff08;二&…

Loj#116-[模板]有源汇有上下界最大流

正题 题目链接:https://loj.ac/p/116 题目大意 nnn个点mmm条边的一张图&#xff0c;每条边有流量上下限制&#xff0c;求源点到汇点的最大流。 解题思路 先别急着求上面那个&#xff0c;考虑一下怎么求无源点汇点的上下界可行流。 可以考虑先把下限流满&#xff0c;这样就会…

【Trie】最长异或路径(ybtoj Trie-3/luogu 4551)

正题 ybtoj Trie-3 luogu 4551 题目大意 给你一棵树&#xff0c;让你找一条路径&#xff0c;使这条路径的亦或值最大 解题思路 对于每个数存下到根节点的亦或值&#xff0c;然后拿这些数去Trie中跑最大亦或 因为相同部分亦或后为0&#xff0c;所以得出结果就是最大路径亦或…

Codeforces Round #663 (Div. 2)

2020/8/9晚上断网了&#xff0c;本来不想打就顺便看看题目&#xff0c;发现能做几个&#xff0c;然后就交了。&#xff08;做完1、2两题才敢交&#xff09;最终做了3个题tcl。 A - Suborrays 脑筋急转弯题目。位运算OR运算结果只会变大不会变小&#xff0c;直接正序输出就可 …

【每日一题】7月16日题目精讲—点权和

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld题目描述 给你一棵树&#xff0c;最开始点权为0&#xff0c;每次将与一个点x树上距离<1的所…

中国开源年会 COSCon 2018 今起接受报名!

大会官网二维码名片&#xff1a;点击文末左下角阅读原文&#xff0c;直达报名链接写在大会前开源 20 年&#xff0c;我们遇到了什么问题&#xff1f;‍围绕开源的方式来开发软件项目&#xff0c;正在走向业界的主流。随着开源的崛起&#xff0c;相应的问题也来了&#xff1a;Re…

【Trie】阅读理解(luogu 3879/ybtoj Trie-4)

正题 luogu 3879 ybtoj Trie-4 题目大意 给你n篇文章&#xff0c;还有m个单词&#xff0c;问你这些单词在哪几篇文章中出现过 解题思路 对文章中的单词建Trie&#xff0c;然后那查询的单词去匹配 代码 #include<map> #include<vector> #include<cstdio> …

P6222-「P6156 简单题」加强版【莫比乌斯反演】

正题 题目链接:https://www.luogu.com.cn/problem/P6222 题目大意 给出kkk&#xff0c;TTT组询问给出nnn求 ∑i1n∑j1n(ij)kgcd(i,j)μ(gcd(i,j))2\sum_{i1}^n\sum_{j1}^n(ij)^k\times gcd(i,j)\times \mu(gcd(i,j))^2i1∑n​j1∑n​(ij)kgcd(i,j)μ(gcd(i,j))2 解题思路 开…

Codeforces Round #664 (Div. 2)

写了三个题结果C fst了O.0 A - Boboniu Likes to Color Balls 回文串&#xff0c;最多有球是一个奇数个。 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<cstdio> #include<iostream> #include<algorithm> using namespace std…

2020 年百度之星·程序设计大赛 - 初赛一

2020 年百度之星程序设计大赛 - 初赛一 [toc] 6743 Drink 题解&#xff1a; 每一种饮料求一个卡路里&#xff0c;取最小值 第一看以为是背包&#xff0c;其实出题人在第二层 代码&#xff1a; #include<iostream> #include<cstdio> #include<string> #i…

.Net Core应用框架Util介绍(四)

上篇介绍了Util Angular Demo的目录结构和运行机制&#xff0c;本文介绍Util封装Angular的基本手法及背后的动机。Angular应用由Ts和Html两部分构成&#xff0c;本文介绍第一部分。Angular Ts的封装Ts是Angular的代码部分&#xff0c;用于编写页面逻辑。依赖注入( Dependency I…

【AC自动机】AC自动机(二次加强版)(luogu 5357)

正题 luogu 5357 题目大意 给你若干单词和一个字符串&#xff0c;让你查询每个单词在字符串中出现的次数 解题思路 AC自动机模板 先把单词丢进去&#xff0c;然后拿字符串去跑&#xff0c;每到一个点累计答案 因为数据较大&#xff0c;所以要先存起来&#xff0c;跑完后按…

Educational Codeforces Round 93 (Rated for Div. 2)

A - Bad Triangle 选出三个序列使之不能组成三角形。先把差距最大的选了&#xff0c;枚举中间值。两边之和不大于第三边。 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> using namespace std; const i…

P4198-楼房重建【线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P4198 题目大意 nnn条线&#xff0c;开始时第iii条是(i,0)(i,0)(i,0)的一个点。 每次有操作把第xxx条线变成(x,0)(x,0)(x,0)到(x,y)(x,y)(x,y)。然后求从(0,0)(0,0)(0,0)能看到几条线。 解题思路 把线变成斜率的话就是对于每…

2020牛客暑期多校训练营(第四场)

2020牛客暑期多校训练营&#xff08;第四场&#xff09; 这场属实有点难受 文章目录A Ancient DistanceB Basic Gcd Problem题目代码&#xff1a;C Count New StringD Dividing StringsE EliminateF Finding the Order题意&#xff1a;题解&#xff1a;代码&#xff1a;G Geome…