首先,我我的以为这套题比较烂。。。除了题干长之外,题目也是有一点恶心。而后重回绿名。c++
A:给你n个相邻的建筑(从左到右编号1到n),每一个建筑有h层,每一个建筑的a层到b层中任意一层c层能够花一秒直接到隔壁建筑的c层。上下楼1层须要1秒。求q次查询(建筑a,层a)到(建筑b,层b)的最短期。惟一的坑点就是同一层楼要特判。(然而我仍是WA了一发)spa
B:老师要问一个同窗a,这我的会说另外一个b,而后老师会批评b,而后b会说同窗c,老师再去批评c,依次下去,直到有一我的被批评了两次。求老师问同窗1~n时,第一次被批评两次的这我的。直接爆搜就能够。。。感受比第一题还简单。。。.net
C:n个选民,m个竞争者(编号1~m),你是1号竞争者。给出每一个选民准备选的竞争者,和让这个选民选你的花费。求最小的花费让你胜出(胜出就是你的票数大于其余任何竞争者的票数)。刚开始准备各类模拟,而后样例都过不了。。。比赛的时候干了一个半小时没干出来。其实方向想错了。应该枚举答案而不是直接模拟过程。由于总有一个得票数i(1<=i<=n),让你胜出。而后枚举每一个i,把得票数大于等于i的竞争者中选他们的选民买通给本身投票,直到他的得票数小于i,而后再看本身票数是否可以达到i,不够补一下。最后能达到就取一下最小费用。code
代码:get
#include<bits/stdc++.h> using namespace std; const int N=3007; typedef long long ll; int n,m,i,j,k; ll ans=1e18,v,cnt; priority_queue<int,vector<int>,greater<int> >e[N],s[N],S; int main(){ for(scanf("%d%d",&n,&m),i=1;i<=n;++i) scanf("%d%d",&j,&k),s[j].push(k); for(i=1;i<=n;++i){ while(!S.empty())S.pop(); cnt=s[1].size(); for(j=2;j<=m;++j)e[j]=s[j]; for(v=0,j=2;j<=m;++j) while(e[j].size()>=i) v+=e[j].top(),e[j].pop(),cnt++; for(j=2;j<=m;++j) while(!e[j].empty())S.push(e[j].top()),e[j].pop(); for(;cnt<i&&!S.empty();++cnt)v+=S.top(),S.pop(); if(cnt>=i)ans=min(ans,v); } printf("%I64d\n",ans); }
本文分享 CSDN - LSD20164388。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。it