1020A - New Building for SIS
#include<cstdio> #include<algorithm> using namespace std; struct X { int t,f; void in() { scanf("%d%d",&t,&f); } }; int jd(int a) { return a>0?a:-a; } int main() { int n,h,a,b,k,ans; scanf("%d%d%d%d%d",&n,&h,&a,&b,&k); while(k--) { X c,d; c.in(),d.in(); if(c.f>d.f) swap(c,d); ans=jd(c.t-d.t); if(!ans) ans=d.f-c.f; else if(c.f>b) ans+=c.f-2*b+d.f; else if(d.f<a) ans+=2*a-d.f-c.f; else ans+=d.f-c.f; printf("%d ",ans); } return 0; }
1020B - Badge
#include<cstdio> const int N=1005; int d[N],c[N],p[N],t,w,q[N],ans[N]; int dfs(int u) { if(d[u]) return u; return ans[u]=dfs(p[u]); } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&p[i]),d[p[i]]++; for(int i=1;i<=n;++i) if(!d[i]) c[i]=1,q[w++]=i; for(;t<w;++t) { d[p[q[t]]]--; if(!d[p[q[t]]]) { q[w++]=p[q[t]]; } } for(int i=1;i<=n;++i) if(c[i]) ans[i]=dfs(i); for(int i=1;i<=n;++i) printf("%d ",d[i]?i:ans[i]); return 0; }
1019A - Elections
题目大意:
某国有n个公民,m个政党。
进行一个选举,得票最高的政党获胜
每个公民有一个起初决定投的政党编号xhi;
但是只要给他ci元,他就能改变自己所投的政党至你想投的。
问要编号为1的政党获胜至少要花多少钱。
解题思路:
这个题数据范围算只是到3000而已。
所以就可以枚举政党获胜的票数为x(x的范围是1一开始有的票数到总数n)
所以其它政党最多拿到x-1票
那么我就通过买ci小的那些人,让其它政党拿到的票数小于x
所以我们此时就只需要从小到大(根据ci)如果这个人对应的政党票数大于等于x那么我们就买通这个人,并且记录此政党票数-1
之后买第一个政党的票数会增大到一定值a,如果a仍然小于x那么我们就买x-a个还没有投第一个政党的人且ci小的人。
最后比较记录答案即可。
#include<cstdio> #include<algorithm> using namespace std; const int N=3005; struct X{ int xh,c,bj; bool operator<(const X &a){ return c<a.c; } }x[N]; int ps[N],tps[N]; int main(){ int n,m,s=0; long long ans=1e18; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ int b,c; scanf("%d%d",&b,&c); if(b-1) x[++s]=(X){b,c,0}; ++ps[b]; } sort(x+1,x+s+1); for(int i=ps[1];i<=n;++i){ long long co=0; for(int j=1;j<=m;++j) tps[j]=ps[j]; for(int j=1;j<=s;++j) if(tps[x[j].xh]>=i){ x[j].bj=1; ++tps[1]; co+=x[j].c; --tps[x[j].xh]; } for(int j=1;tps[1]<i;++j) if(!x[j].bj){ ++tps[1]; co+=x[j].c; } if(co<ans) ans=co; for(int j=1;j<=s;++j) x[j].bj=0; } printf("%I64d",ans); return 0; }