JOI予選参加記
JOI 2015/2016 予選 問題文・採点用入出力・解説
こことのdiffを取ってみたら520だった
適当な解説とソースコードだけ貼ります
問1
やるだけ
int main(){ int a[4],b[2]; REP(i,4)cin>>a[i]; REP(i,2)cin>>b[i]; sort(a,a+4); sort(b,b+2); cout<<a[3]+a[2]+a[1]+b[1]<<endl; return 0; }
問2
swapでゴリ押し
int a[110]; int main(){ int n,m; cin>>n>>m; REP(i,n)cin>>a[i]; for(int k=1;k<=m;k++){ REP(i,n-1){ if(a[i]%k>a[i+1]%k){ swap(a[i],a[i+1]); } } } REP(i,n)cout<<a[i]<<endl; return 0; }
問3
dp解もあるらしいけど全探索しました char fld[55][55]; int h,w; int rec(int r,int l){ int cnt=0; for(int i=0;i<=r;i++)REP(j,w)if(fld[j][i]!='W')cnt++; for(int i=r+1;i<=l;i++)REP(j,w)if(fld[j][i]!='B')cnt++; for(int i=l+1;i<h;i++)REP(j,w)if(fld[j][i]!='R')cnt++; return cnt; } int main(){ cin>>h>>w; REP(i,h)REP(j,w)cin>>fld[j][i]; int ans=INF; for(int i=0;i<h;i++){ for(int j=i+1;j<h-1;j++){ ans=min(ans,rec(i,j)); } } cout<<ans<<endl; return 0; }
問4
隣同士で左側が東、右側が西になっている(反対側にすすんでいく)場所を保存してほげ
int n,q,d[100100]; ll t,a[100100]; ll dist[100100]; vector<int> dat; int main(){ scanf("%d%lld%d",&n,&t,&q); REP(i,n){ scanf("%lld%d",&a[i],&d[i]); } if(d[0]==1)dat.PB(0); REP(i,n-1){ if(d[i]==2&&d[i+1]==1)dat.PB(i+1); } if(d[n-1]==2)dat.PB(n); for(int i=0;i<dat[0];i++){ dist[i]=a[i]-t; } for(int i=0;i<dat.size()-1;i++){ ll btw; for(int j=dat[i];j<dat[i+1]-1;j++){ if(d[j]==1&&d[j+1]==2){ btw=(a[j]+a[j+1])/2LL; } } for(int j=dat[i];j<dat[i+1];j++){ if(d[j]==1){ dist[j]=min(a[j]+t,btw); }else{ dist[j]=max(a[j]-t,btw); } } } for(int i=dat[dat.size()-1];i<n;i++){ dist[i]=a[i]+t; } int x; REP(i,q){ scanf("%d",&x);x--; cout<<dist[x]<<endl; } return 0; }
問5
幅とダイクストラゴリ押し
計算量考えてなかったけどなんかできた
int n,m,k,s,p,q,c[100100]; ll d[100100]; bool ok[100100]; bool no[100100]; bool used[100100]; vector<int> G[100100]; ll INF =(1<<29)-1; void dijkstra(int s){ priority_queue<P,vector<P>,greater<P> > Q; fill(d,d+n,LLONG_MAX); d[s]=0; Q.push(P(0,s)); while(!Q.empty()){ P pp=Q.top();Q.pop(); int v=pp.second; if(d[v]<pp.first)continue; if(no[v])continue; for(int i=0;i<G[v].size();i++){ int to=G[v][i]; int cost=(ok[to]?q:p); if(d[to]>d[v]+cost){ d[to]=d[v]+cost; Q.push(P(d[to],to)); } } } } int main(){ memset(ok,false,sizeof(ok)); memset(no,false,sizeof(no)); scanf("%d%d%d%d",&n,&m,&k,&s); scanf("%d%d",&p,&q); REP(i,k)scanf("%d",&c[i]); REP(i,m){ int a,b; scanf("%d%d",&a,&b);a--;b--; G[a].PB(b);G[b].PB(a); } REP(i,k){ c[i]--; memset(used,false,sizeof(used)); no[c[i]]=ok[c[i]]=true; queue<P> Q; Q.push(P(c[i],0)); while(!Q.empty()){ P pp=Q.front();Q.pop(); if(pp.second>=s)break; int v=pp.first; REP(i,G[v].size()){ int to=G[v][i]; if(!used[to]){ used[to]=true; ok[to]=true; Q.push(P(to,pp.second+1)); } } } } dijkstra(0); if(ok[n-1])cout<<d[n-1]-q<<endl; else cout<<d[n-1]-p<<endl; return 0; }
問6
bitDPだなーと思って実装してたらわけわからなくなって死
6-1だけ紙で解いた
問6に1時間半以上も残したのに解けなかったのが痛かった
ボーダーは全完って聞いてるので予選落ちです