2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)
题目链接:http://codeforces.com/contest/589
I题:水题签到。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1000100; const int INF=(1<<29); int cnt[maxn]; int n,k,a; int main() { //freopen("in.txt","r",stdin); while(cin>>n>>k){ MS0(cnt); REP(i,1,n) scanf("%d",&a),cnt[a]++; int x=n/k,ans=0; REP(i,1,k){ ans+=abs(cnt[i]-x); } cout<<ans/2<<endl; } return 0; }
J题:水题,模拟。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=30; const int INF=(1<<29); int dir[maxn*maxn*maxn]; int n,m; bool vis[maxn][maxn][4]; char ch[maxn][maxn]; int sx,sy,sdir; int ans; bool vi[maxn][maxn]; void Init() { dir['L']=0; dir['U']=1; dir['R']=2; dir['D']=3; } bool can(int x,int y,int d) { if(x<1||x>n||y<1||y>m) return 0; return ch[x][y]=='.'; } void dfs(int x,int y,int d) { if(vis[x][y][d]) return; vis[x][y][d]=1; if(!vi[x][y]) ans++,vi[x][y]=1; //cout<<x<<" "<<y<<" "<<ans<<" "<<endl; if(d==0){ if(can(x,y-1,d)) dfs(x,y-1,d); else dfs(x,y,(d+1)%4); } else if(d==1){ if(can(x-1,y,d)) dfs(x-1,y,d); else dfs(x,y,(d+1)%4); } else if(d==2){ if(can(x,y+1,d)) dfs(x,y+1,d); else dfs(x,y,(d+1)%4); } else{ if(can(x+1,y,d)) dfs(x+1,y,d); else dfs(x,y,(d+1)%4); } } int main() { //freopen("in.txt","r",stdin); Init(); while(cin>>n>>m){ MS0(vis); MS0(vi); REP(i,1,n){ REP(j,1,m){ cin>>ch[i][j]; if(isupper(ch[i][j])){ sx=i,sy=j; sdir=dir[ch[i][j]]; ch[i][j]='.'; } } } ans=0; dfs(sx,sy,sdir); cout<<ans<<endl; } return 0; }
B题:贪心水题。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1000100; const int INF=(1<<29); int n; struct Node { ll a,b; }; Node rec[maxn]; vector<ll> w; bool cmp1(Node A,Node B) { if(A.a<B.a) return 1; if(A.a==B.a) return A.b<B.b; return 0; } int sb() { int m=0; int sz=(int)w.size(); for(int i=0;i<w.size();i++){ if(w[i]*(sz-i)>=w[m]*(sz-m)) m=i; } return m; } int main() { //freopen("in.txt","r",stdin); while(cin>>n){ w.clear(); REP(i,1,n){ scanf("%I64d%I64d",&rec[i].a,&rec[i].b); if(rec[i].a<rec[i].b) swap(rec[i].a,rec[i].b); w.push_back(rec[i].b); } sort(rec+1,rec+n+1,cmp1); sort(w.begin(),w.end()); ll ans=0,ansx,ansy; REP(i,1,n){ int p=sb(); ll x=rec[i].a,y=w[p]; ll cnt=(int)w.size()-p; if(x*y*cnt>ans){ ans=x*y*cnt; ansx=x;ansy=y; } vector<ll>::iterator it=find(w.begin(),w.end(),rec[i].b); w.erase(it); } cout<<ans<<endl; cout<<ansx<<" "<<ansy<<endl; } return 0; }
F题:二分+贪心+线段树。二分是二分时间t。贪心是给右端点排序以确定安排的优先级,分类讨论可证明贪心的正确性。线段树是区间更新和统计可用的时间。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=100100; const int INF=(1<<29); int n; struct Node { int s,t; friend bool operator<(Node A,Node B) { if(A.t<B.t) return 1; if(A.t==B.t) return A.s<B.s; return 0; } };Node dish[maxn]; struct SegTree { int l,r; int cnt; int lazy; int id; };SegTree T[maxn<<2]; const int N=100010; void push_up(int rt) { T[rt].cnt=T[rt<<1].cnt+T[rt<<1|1].cnt; } void push_down(int rt) { if(T[rt].lazy){ T[rt<<1].lazy=T[rt<<1|1].lazy=1; T[rt<<1].cnt=T[rt<<1|1].cnt=0; T[rt].lazy=0; } } void build(int l,int r,int rt) { T[rt].l=l;T[rt].r=r; T[rt].lazy=0; if(l==r){ T[rt].cnt=1; T[rt].id=l; return; } push_down(rt); int m=(l+r)>>1; build(lson); build(rson); push_up(rt); } void update(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R){ T[rt].lazy=1; T[rt].cnt=0; if(l==r) T[rt].lazy=0; return; } push_down(rt); int m=(l+r)>>1; if(L<=m) update(L,R,lson); if(R>m) update(L,R,rson); push_up(rt); } int query_cnt(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return T[rt].cnt; push_down(rt); int m=(l+r)>>1; int res=0; if(L<=m) res+=query_cnt(L,R,lson); if(R>m) res+=query_cnt(L,R,rson); return res; } int query_pos(int p,int l,int r) { while(l<r){ int m=(l+r)>>1; int lcnt=query_cnt(l,m,1,N,1); if(lcnt>=p) r=m; else p-=lcnt,l=m+1; } return l; } bool check(int t) { build(1,N,1); REP(i,1,n){ int L=dish[i].s,R=dish[i].t; int cnt=query_cnt(L,R,1,N,1); if(cnt<t) return 0; int a=query_pos(1,L,R),b=query_pos(t,L,R); update(a,b,1,N,1); } return 1; } int bin(int l,int r) { int res=0; while(l<r){ int m=(l+r)>>1; if(check(m)) l=m+1,res=max(res,m); else r=m; } return res; } int main() { // freopen("in.txt","r",stdin); while(cin>>n){ REP(i,1,n) scanf("%d%d",&dish[i].s,&dish[i].t),dish[i].s++; sort(dish+1,dish+n+1); cout<<bin(0,N)*n<<endl; } return 0; }