JOI2018/2019予選参加記
520点。そこそこ相性がよかったので楽だった(実装はボロボロでしたが)
1問目:ソーシャルゲーム
Cの制約見えてなくて1WA。何やってるんだ。
#include "bits/stdc++.h" using namespace std; using ll=long long; using ull=unsigned long long; typedef pair<int,int>Pi; typedef pair<long long,long long>P; typedef pair<long long,P>PP; typedef pair<P,P>PPP; const long long MOD=1e9+7; const long long INF=5e18; const int di[4]={1,0,-1,0}; const int dj[4]={0,1,0,-1}; #define fr first #define sc second #define pb push_back #define eb emplace_back #define ALL(x) (x).begin(),(x).end() int a,b,c; void input(){ cin>>a>>b>>c; return; } void solve(){ for(int i=1;i<=1000000;i++){ if(i%7==0)c-=b; c-=a; if(c<=0){ cout<<i<<endl; return; } } return; } int main(){ input(); solve(); return 0; }
2問目:すごろくと駒
1問目より楽...?
#include "bits/stdc++.h" using namespace std; using ll=long long; using ull=unsigned long long; typedef pair<int,int>Pi; typedef pair<long long,long long>P; typedef pair<long long,P>PP; typedef pair<P,P>PPP; const long long MOD=1e9+7; const long long INF=5e18; const int di[4]={1,0,-1,0}; const int dj[4]={0,1,0,-1}; #define fr first #define sc second #define pb push_back #define eb emplace_back #define ALL(x) (x).begin(),(x).end() int n,m,a[1010],b[1010]; void input(){ cin>>n; for(int i=0;i<n;i++)cin>>a[i]; cin>>m; for(int i=0;i<m;i++)cin>>b[i]; return; } void solve(){ a[n]=2020; for(int i=0;i<m;i++){ if(a[b[i]-1]+1==a[b[i]])continue; a[b[i]-1]++; } for(int i=0;i<n;i++){ cout<<a[i]<<endl; } return; } int main(){ input(); solve(); return 0; }
3問目:マルバツスタンプ
適当な貪欲を書くと通る。(番兵の意味とは)
#include "bits/stdc++.h" using namespace std; using ll=long long; using ull=unsigned long long; typedef pair<int,int>Pi; typedef pair<long long,long long>P; typedef pair<long long,P>PP; typedef pair<P,P>PPP; const long long MOD=1e9+7; const long long INF=5e18; const int di[4]={1,0,-1,0}; const int dj[4]={0,1,0,-1}; #define fr first #define sc second #define pb push_back #define eb emplace_back #define ALL(x) (x).begin(),(x).end() int n,ans; bool flx,flo; string s; void input(){ cin>>n>>s; s+='$'; return; } void solve(){ for(int i=0;i<n;i++){ if(!flx&&s[i]=='X')flx=true; if(!flo&&s[i]=='O')flo=true; if(flx&&flo){ flx=false; flo=false; ans++; } } cout<<ans<<endl; return; } int main(){ input(); solve(); return 0; }
4問目:日本沈没
島が分断されるか、消えるかを見て足し引きすればよし。座圧して、高さが低い順に島を見たときに、両隣りが沈んでいるか、まだ残っているか、否かで場合分けしていけばOK。
#include "bits/stdc++.h" using namespace std; using ll=long long; using ull=unsigned long long; typedef pair<int,int>Pi; typedef pair<long long,long long>P; typedef pair<long long,P>PP; typedef pair<P,P>PPP; const long long MOD=1e9+7; const long long INF=5e18; const int di[4]={1,0,-1,0}; const int dj[4]={0,1,0,-1}; #define fr first #define sc second #define pb push_back #define eb emplace_back #define ALL(x) (x).begin(),(x).end() int n,a[100010],ans,cnt; vector<int>v; vector<int>it[100010]; bool deep[100010]; void input(){ cin>>n; v.eb(0); for(int i=0;i<n;i++){ cin>>a[i]; deep[i]=true; v.eb(a[i]); } sort(ALL(v)); v.erase(unique(ALL(v)),v.end()); for(int i=0;i<n;i++){ int num=lower_bound(ALL(v),a[i])-v.begin(); it[num].eb(i); } return; } void solve(){ for(int i=0;i<v.size();i++){ for(int j=0;j<it[i].size();j++){ int now=it[i][j]; if(now==0){ if(!deep[1])cnt--; deep[0]=false; } else if(now==n-1){ if(!deep[n-2])cnt--; deep[n-1]=false; } else{ if(deep[now-1]&&deep[now+1])cnt++,deep[now]=false; else if(!deep[now-1]&&!deep[now+1])cnt--,deep[now]=false; else deep[now]=false; } } ans=max(ans,cnt+1); } cout<<ans<<endl; return; } int main(){ input(); solve(); return 0; }
5問目:イルミネーション
i番目の木を飾った時、次に飾ることができる最も近い木へ遷移するDP。どこから飾れるかは、遅延セグ木を用いて求めた。どこにも属していない木は最後にまとめて足しました。
(セグ木は長いのでカットしてあります)
#include "bits/stdc++.h" using namespace std; using ll=long long; using ull=unsigned long long; typedef pair<int,int>Pi; typedef pair<long long,long long>P; typedef pair<long long,P>PP; typedef pair<P,P>PPP; const long long MOD=1e9+7; const long long INF=5e18; const int di[4]={1,0,-1,0}; const int dj[4]={0,1,0,-1}; #define fr first #define sc second #define pb push_back #define eb emplace_back #define ALL(x) (x).begin(),(x).end() int n,m; P p[200010]; vector<ll>v; ll a[200010],dp[200010],ans; void input(){ cin>>n>>m; v.resize(n); for(int i=0;i<n;i++)cin>>a[i]; for(int i=0;i<m;i++){ cin>>p[i].sc>>p[i].fr; p[i].fr--,p[i].sc--; } sort(p,p+m); return; } void solve(){ LazySegmentTree nex(v); for(int i=0;i<m;i++){ nex.update(p[i].sc,p[i].fr+1,p[i].fr+1); } for(int i=0;i<n;i++){ dp[i+1]=max(dp[i+1],dp[i]); if(nex.find(i,i+1)==0)continue; dp[nex.find(i,i+1)]=max(dp[nex.find(i,i+1)],dp[i]+a[i]); ans=max(ans,dp[nex.find(i,i+1)]); ans=max(dp[i+1],ans); } for(int i=0;i<n;i++){ if(nex.find(i,i+1)==0)ans+=a[i]; } cout<<ans<<endl; return; } int main(){ input(); solve(); return 0; }
6問目:座席
20点だけもらった。4進数にして残っている人数を管理し、前の人が誰かを持っておきながら配列を使いまわす(メモリがきつい)。同じ国の人の並べ方は最後に階乗をかければOK。100点は知りません。
#include "bits/stdc++.h" using namespace std; using ll=long long; using ull=unsigned long long; typedef pair<int,int>Pi; typedef pair<long long,long long>P; typedef pair<long long,P>PP; typedef pair<P,P>PPP; const long long MOD=1e9+7; const long long INF=5e18; const int di[4]={1,0,-1,0}; const int dj[4]={0,1,0,-1}; #define fr first #define sc second #define pb push_back #define eb emplace_back #define ALL(x) (x).begin(),(x).end() int n,a[110]; int dp[2][1100000][11]; int sum,till,ans; int fact[40]; vector<int>v[1100000]; void input(){ cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; sum+=a[i]; } return; } void solve(){ if(n>10)return; fact[0]=1; for(int i=0;i<n;i++){ till+=fact[i]*a[i]; fact[i+1]=fact[i]*4; } for(int i=1;i<=till;i++){ int c=i; while(true){ v[i].eb(c%4); c/=4; if(c<4){ v[i].eb(c); break; } } } for(int i=0;i<n;i++){ dp[0][till-fact[i]][i]=1; } for(int i=1;i<sum;i++){ for(int j=1;j<=till;j++){ for(int k=0;k<n;k++){ if(dp[(i-1+2)%2][j][k]==0)continue; for(int l=0;l<n;l++){ if(k==l||k==l-1||k==l+1)continue; if(l>=v[j].size())continue; if(v[j][l]==0)continue; int s=j-fact[l]; dp[i%2][s][l]+=dp[(i-1+2)%2][j][k]; dp[i%2][s][l]%=10007; } } } for(int j=0;j<=till;j++){ for(int k=0;k<n;k++){ dp[(i-1+2)%2][j][k]=0; } } } for(int i=0;i<n;i++){ ans+=dp[(sum+1)%2][0][i]; ans%=10007; } for(int i=0;i<n;i++){ while(a[i]){ ans*=a[i]; a[i]--; ans%=10007; } } cout<<ans<<endl; return; } int main(){ input(); solve(); return 0; }