WC 2022 题单及部分题解
自己整理的题单,会补充部分题解,中文题目自己去洛谷。
题单全部
#### Day 1 上午
- [x] [部分背包问题](https://www.luogu.com.cn/problem/P2240)
- [ ] [田忌赛马](https://www.luogu.com.cn/problem/P1650) NT 不写
- [ ] [「USACO 2.1」三值排序](https://www.luogu.com.cn/problem/P1459) NT 不写
- [ ] [Equality Control](https://codeforces.com/gym/102483/problem/E)
- [x] [Game Relics](https://codeforces.com/contest/1267/problem/G)
- [ ] [Canvas Line](https://codeforces.com/gym/102500/problem/C)
- [ ] [Assigning Workstations](https://codeforces.com/gym/101485)
- [ ] [Swap Space](https://codeforces.com/gym/101242)
- [ ] [Quest](https://loj.ac/p/6798)
- [ ] [Interactive Knockout](https://codeforces.com/gym/102896/problem/I)
- [ ] [The Mind](https://codeforces.com/contest/1578/problem/M)
- [ ] [Flipping coins](https://ipsc.ksp.sk/2011/real/problems/f.html) IPSC 不写
- [x] [Is It Rated?](https://codeforces.com/contest/1510/problem/I)
- [ ] [Framing Pictures](https://codeforces.com/contest/1578/problem/F)
- [ ] [Fiber Shape ](https://codeforces.com/contest/1510/problem/F)
- [ ] [Connect Dots](https://codeforces.com/gym/101623)
- [ ] [Screamers in the Storm](https://contest.felk.cvut.cz/19cerc/solved.html)
- [ ] [Convex Polyhedron](https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5532)
- [ ] [New Flat](https://codeforces.com/gym/102896/problem/N)
- [ ] [Cow Photography](https://www.luogu.com.cn/problem/P3034)
- [ ] 「WC2003」圣诞礼物
- [ ] [Anti-Tetris](https://codeforces.com/contest/1578/problem/A)
- [ ] [Access Points](https://codeforces.com/gym/102483/problem/A)
- [x] [Juggling Troupe](https://codeforces.com/gym/101623/problem/J)
- [ ] [Better Productivity](https://codeforces.com/gym/101485/problem/B)
- [ ] [Game of Chance](https://codeforces.com/contest/1578/problem/G)
- [ ] [Chess Pieces](https://ipsc.ksp.sk/2015/real/problems/c.html) IPSC 不写
- [ ] [Kitesurfing](https://codeforces.com/gym/102500/problem/K)
- [x] [Date Pickup](https://codeforces.com/gym/102483/problem/D)
- [ ] [Maximum enjoyment](https://ipsc.ksp.sk/2014/real/problems/m.html) IPSC 不写
- [ ] [Scenery](https://codeforces.com/gym/101471/problem/H)
- [ ] [Pipe Stream](https://codeforces.com/gym/101239/problem/G)
- [ ] [Son of Pipe Stream](https://loj.ac/p/6479)
- [ ] [Fish Fillets](https://ipsc.ksp.sk/2009/real/problems/f.html) IPSC 不写
- [ ] [What Really Happened on Mars?](https://codeforces.com/gym/101242/problem/M)
#### Day1 营员交流
- [ ] [理论复杂度](https://uoj.ac/problem/696)
- [x] [Coins](https://atcoder.jp/contests/agc018/tasks/agc018_c)
- [ ] [「NOI2019」序列](https://www.luogu.com.cn/problem/P5470)
- [ ] [「BJWC2018」餐巾计划问题](https://www.luogu.com.cn/problem/P4480)
- [ ] [跳伞求生](https://darkbzoj.tk/problem/4977)
- [ ] [Homework Scheduling](https://atcoder.jp/contests/nikkei2019-final/tasks/nikkei2019_final_h)
- [ ] [「CTSC2010」产品销售](https://www.luogu.com.cn/problem/P4217)
- [ ] [Conquer The World](https://www.luogu.com.cn/problem/P6943)
#### Day2 下午
- [ ] [「IOI2021」位移寄存器](https://loj.ac/p/3528)
- [ ] [「IOI2021」地牢游戏](https://loj.ac/p/3527)
- [ ] [「UNR 5」诡异操作](https://uoj.ac/problem/671)
- [ ] [新年的聚会](https://uoj.ac/problem/592)
- [x] [「UER 9」赶路](https://uoj.ac/problem/604)
- [ ] [Red Blue Tree](https://www.luogu.com.cn/problem/CF1208H)
- [x] [Logistical Questions](https://www.luogu.com.cn/problem/CF566C)
- [ ] [Max Mex](https://www.luogu.com.cn/problem/CF1083C)
- [ ] [「JOISC 2019 Day3」穿越时空 Bitaro](https://loj.ac/p/3038)
- [ ] [Knowledge Is...](https://codeforces.com/gym/102979/problem/K)
- [ ] [Yosupo’s Algorithm](https://codeforces.com/gym/102586/problem/L)
- [ ] [美好的每一天~ 不连续的存在](https://www.luogu.com.cn/problem/P6580)
#### Day2 营员交流
- [ ] [Bytehattan](https://bzoj.org/d/nboj/p/P000355)
- [ ] [「WC2013」平面图](https://www.luogu.com.cn/problem/P4073)
#### Day3 上午
- [ ] Stars
- [ ] [PA 2021 Round1 A](https://qoj.ac/contest/734/problem/2115)
- [ ] [基础博弈练习题](http://zhengruioi.com/problem/1702)
- [ ] [PA 2021 Round2 A](https://qoj.ac/contest/735/problem/2118)
- [ ] [Queue at the Bakery](https://www.codechef.com/SNCKFL21/problems/BAKERY)
- [ ] [Scrupulous Robbery Plan](https://www.codechef.com/SNCKFL21/problems/ROBBERYPLAN)
- [ ] [Random Pawn](https://atcoder.jp/contests/agc044/tasks/agc044_e)
- [ ] [Cheese](https://atcoder.jp/contests/agc056/tasks/agc056_e)
- [ ] [Secret of Tianqiu Valley](https://codeforces.com/gym/103470/problem/L)
- [ ] [Help BerLine](https://codeforces.com/contest/1267/problem/H)
- [x] [Flop Sorting](https://loj.ac/p/3519)
#### Day3 下午
- [ ] [「IOI2021」喷泉公园](https://loj.ac/p/3525)
- [ ] 挑战哈密顿 2
- [ ] [Pattern Lock](https://codeforces.com/gym/103495/problem/D)
- [ ] [Secret of Tianqiu Valley](https://codeforces.com/gym/103470/problem/L)
- [ ] 开关
- [ ] [「ROI 2018 Day 2」快速排序](https://loj.ac/p/2848)
- [ ] [Balance the Cards](https://codeforces.com/contest/1503/problem/F)
- [ ] [最大生成掌](http://120.27.222.204:12243/problem/702)
- [ ] [Evil](https://codeforces.com/contest/329/problem/E)
- [ ] Jeopardy
- [ ] [GCD Land](https://codeforces.com/gym/102055/problem/C)
- [ ] [City](https://atcoder.jp/contests/joisc2017/tasks/joisc2017_k)
- [ ] [大鱼划水](https://loj.ac/p/3392)
- [ ] [仓颉造数](https://vjudge.net/problem/HDU-7092)
- [ ] [同构判定海蜇](http://120.27.222.204:12243/problem/712)
#### Day4 上午
- [ ] [「IOI2002」Batch Scheduling](http://poj.org/problem?id=1180)
- [ ] [「IOI2002」Bus Terminals](http://poj.org/problem?id=1181)
- [ ] [「IOI2002」Two Rods](https://ioinformatics.org/files/ioi2002problem6.pdf)
- [ ] [「IOI2008」Pyramid Base](https://www.luogu.com.cn/problem/P4687)
- [ ] [通信中位数](http://www.matrix67.com/blog/archives/5342) m67 有讲解了,不写
- [ ] [The Riddle of the Sphinx](https://www.luogu.com.cn/problem/CF1466I)
- [ ] [Santa's Candy Factory](https://dmoj.ca/problem/wac6p6)
- [ ] [「IOI2020」数蘑菇](https://loj.ac/p/3368)
- [ ] [「IOI2018」机械娃娃](https://loj.ac/p/2866)
- [ ] [「IOI2017」西默夫](https://loj.ac/p/3173)
- [ ] [「IOI2012」Pebbling odometer](http://www.ioi2012.org/competition/tasks/index.html)
- [ ] [「IPSC 2014」Empathy system](https://ipsc.ksp.sk/2014/real/problems/e.html) IPSC 不写
- [ ] [「IOI2010」Hotter Colder](https://ioinformatics.org/page/ioi-2010/36)
- [ ] [「IOI2010」Save it](https://ioinformatics.org/page/ioi-2010/36)
#### Day4 下午
- [ ] [「IOI2021」分糖果](https://loj.ac/p/3523)
- [ ] [「IOI2021」钥匙](https://loj.ac/p/3524)
- [ ] [History course](https://www.luogu.com.cn/problem/P7013)
- [x] [Gem Island](https://www.luogu.com.cn/problem/P6944)
- [ ] [Gem Island 2](https://loj.ac/p/3405)
- [ ] [Count Min Ratio](https://codeforces.com/gym/102978/problem/C)
- [ ] [「CCO 2021」商旅](https://loj.ac/p/3580)
- [ ] [「WF 2014」Pachinko](https://www.luogu.com.cn/problem/P6899)
- [ ] [「WF 2019」Traffic Blights](https://www.luogu.com.cn/problem/P6261)
CF1267G Game Relics
神仙题只好复读题解。
Solution
不妨考虑先抽卡再买卡,这样一定最优。
如果现在已经有了 \(i\) 张卡,那么抽到第 \(i+1\) 张卡的期望花费是 \((\frac{n}{n-i}+1)\times \frac x 2\)。
把买卡修改一下下,也变成随机抽卡,花费则是抽到的卡的花费。
那么,买卡的期望花费是不是 \(\frac{\sum c_i}{k}\),\(k\) 是剩下的卡的个数。
设 \(f_{i,c}\) 表示买了 \(i\) 张卡,总和是 \(c\),大力 DP 即可。
时间复杂度 \(O(n^2\sum c_i)\)。
Code
const int N=100,V=10000;
int n,c[N+10],x,sum;
db f[N+10][V+10],fac[N+10];
db C(int n,int m) {
return fac[n]/(fac[n-m]*fac[m]);
}
int main() {
scanf("%d %d",&n,&x);
fac[0]=1,f[0][0]=1;
for(int i=1;i<=n;i++) scanf("%d",&c[i]),sum+=c[i],fac[i]=1.0*fac[i-1]*i;
for(int i=1;i<=n;i++)
for(int j=n;j>=1;j--)
for(int k=sum;k>=c[i];k--)
f[j][k]=f[j][k]+f[j-1][k-c[i]];
db ans=0;
for(int i=0;i<=n-1;i++)
for(int j=0;j<=sum;j++)
ans+=f[i][j]/C(n,i)*min(1.0*(sum-j)/(n-i),(1.0*n/(n-i)+1)*x/2);
printf("%.10lf\n",ans);
}
CF1510I Is It Rated?
Solution
一个简单的想法是大佬带我飞!谁答对的多我跟谁!
实际上这一定不行,实际正确率可能很低很低。
考虑加权,也就是说,前 \(n\) 个人看成投票,一个人投上一定权重的票,实现的时候我取 \(\beta^x\),\(x\) 表示这个人答对了多少次,\(\beta\) 是一个选定的实数。
诶是不是觉得很对,这样没有人可以坑我了,实现之后 WA On #26。
为什么过不去呢?其实有很大的可能会被恶意构造导致有人坑你。
为了防止出题人的恶意,我们直接按照求出来的票数的比重,再随一波机。
复杂度 \(O(nm)\),实现时为了防止浮点溢出可以用 \(x-\min c_i\) 代替 \(x\),\(c_i\) 是一个人答错的次数。
Code
mt19937 rng(time(0));
const int N=1e3,M=1e4;
const db Beta=6.0/7;
int n,m,cnt[N+10],y;
db vot1,vot2;
char ch[N+10];
int main() {
scanf("%d %d",&n,&m);
while(m--) {
scanf("%s",ch+1);
vot1=0,vot2=0;
for(int i=1;i<=n;i++)
if(ch[i]=='0') vot1+=pow(Beta,cnt[i]-y);
else vot2+=pow(Beta,cnt[i]-y);
db z=rng()%1000000/1000000.0;
if(z<=vot1/(vot1+vot2)) puts("0");
else puts("1");
fflush(stdout);
int x;scanf("%d",&x);
for(int i=1;i<=n;i++) if(ch[i]!=x+'0') cnt[i]++;
y=m+10;
for(int i=1;i<=n;i++) y=min(cnt[i],y);
}
}
NWERC 2017 Juggling Troupe
有 \(n\) 个菜鸟杂技演员在上面表演杂耍,每个人手里最多两个球,如果他手里有两个球或更多,他会向与他相邻的两个人处丢一个球,求出最后每个人的手里的球的个数。
\(1\le n\le 10^6\)。
Solution
Key observation:对于一个区间 \([L,R]\),如果这之中有一个 \(2\),且其余的元素除 \(L,R\) 均不为 \(1\),且 \(a_{L}=a_{R}=0\),那么这个区间边界会变成 \(1\),并且会出现一个 \(0\),位置在 \(L+R-i\)。
可以自行模拟证明。
Key observation:\(2\) 互不影响。
根据这个,将 \(0\) 的所有位置塞到 set 里,按顺序扫描每个 \(2\),按上述做法模拟即可。
时间复杂度 \(O(n\log n)\)。
Code
const int N=1e6;
set<int> T;
int n,a[N+10];
char ch[N+10],ans[N+10];
int main() {
scanf("%s",ch+1);
n=strlen(ch+1);
T.insert(0),T.insert(n+1);
for(int i=1;i<=n;i++) a[i]=ch[i]-'0';
for(int i=1;i<=n;i++) if(a[i]==0) T.insert(i);
for(int i=1;i<=n;i++)
if(a[i]==2) {
int L,R;
auto tmp=T.lower_bound(i);
R=*tmp,L=*(--tmp);
if(L>=1) T.erase(L);
if(R<=n) T.erase(R);
T.insert(L+R-i);
}
for(int i=1;i<=n;i++) ans[i]='1';
for(auto i:T) ans[i]='0';
for(int i=1;i<=n;i++) putchar(ans[i]);
puts("");
}
NWERC 2018 Date Pickup
现在要在一个有向图上从点 \(1\) 出发游走,在时间 \([a,b]\) 内会有人在某个时刻通知你要到达点 \(n\),要求拖延的时间尽可能的少。
\(2\le n\le m\le 10^5\),\(0\le a\le b\le 10^{12}\)。
Solution
大力求答案,不大可行的样子。
考虑二分一个拖延时间 \(x\),接下来考虑如何在线性时间内判定,以下是判定方法:
- 如果 \(\text{dist}(1,u)+\text{dist}(u,n)\le a+x\),那么一个点是好点:这是因为如果时刻 \(a\) 通知了,那么如果不满足这个条件,是怎样也赶不到的。
- 考虑扩展好点,如果有一条边 \((u,v,w)\) 并且 \(w+\text{dist}(v,n)\le x\),那么 \(v\) 与这条边均是好的:这是因为如果正在穿越这条边是通知了,那么拖延的时间一定 \(\le x\)。
- 将好边与好点的导出子图建出,然后这个子图如果有环,那么可以摸鱼一直到通知。
- 否则,导出子图是一个 DAG,跑一遍 DAG 上 DP 求出最多可以摸鱼的时间就可以了。
check 的复杂度是 \(O(n)\) 的,那么总时间复杂度是 \(O(n\log V)\) 的,于是这题做完了。
Code
const int N=1e5;
const ll inf=1e18;
ll S,T;
int n,m,dis[N+10];
pii E[N+10];
vector<pii> G[N+10];
vector<ll> dis1,disn;
priority_queue<pli> pq;
bool vis[N+10];
void dijskra(int S,vector<ll> &dis) {
while(pq.size()) pq.pop();
for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=0;
pq.push({0,S});dis[S]=0;
while(pq.size()) {
int u=pq.top().se;pq.pop();
if(vis[u]) continue;
vis[u]=1;
for(auto i:G[u]) {
ll d=i.se;int v=i.fi;
if(dis[v]>dis[u]+d)
dis[v]=dis[u]+d,pq.push({-dis[v],v});
}
}
}
vector<pil> DC[N+10];
bool ok[N+10],ext[N+10];
int deg[N+10];
ll f[N+10];
void bfs(ll x) {
memset(deg,0,sizeof deg);memset(ext,0,sizeof ext);
queue<int> q;
for(int i=1;i<=n;i++) {
DC[i].clear();
if(ok[i]&&dis1[i]+disn[i]<=S+x) q.push(i),ext[i]=1;
}
while(q.size()) {
int u=q.front();q.pop();
for(auto i:G[u])
if(i.se+disn[i.fi]<=x) {
if(!ext[i.fi]) q.push(i.fi),ext[i.fi]=1;
DC[u].pb(i),deg[i.fi]++;
}
}
}
bool topsort(ll x) {
for(int i=1;i<=n;i++) f[i]=-inf;
queue<int> q;
for(int i=1;i<=n;i++) if(ext[i]&&!deg[i]) q.push(i);
while(q.size()) {
int u=q.front();q.pop();
if(dis1[u]+disn[u]<=S+x) f[u]=max(f[u],S+x-disn[u]);
if(f[u]>=T) return 1;
for(auto i:DC[u]) {
f[i.fi]=max(f[i.fi],f[u]+i.se);
if(--deg[i.fi]==0) q.push(i.fi);
}
}
for(int i=1;i<=n;i++) if(ext[i]&°[i]) return 1;
return 0;
}
bool check(ll x) {
for(int i=1;i<=n;i++) ok[i]=(disn[i]<=x);
if(ok[1]) return 1;bfs(x);
return topsort(x);
}
int main() {
scanf("%lld %lld %d %d",&S,&T,&n,&m);
for(int i=1;i<=m;i++) scanf("%d %d %d",&E[i].fi,&E[i].se,&dis[i]);
for(int i=1;i<=m;i++) G[E[i].se].pb({E[i].fi,dis[i]});
dis1.resize(n+1),disn.resize(n+1);
dijskra(n,disn);
for(int i=1;i<=n;i++) G[i].clear();
for(int i=1;i<=m;i++) G[E[i].fi].pb({E[i].se,dis[i]});
dijskra(1,dis1);
ll L=0,R=1e18,ans=0;
while(L<=R) {
ll mid=(L+R)>>1;
if(check(mid)) ans=mid,R=mid-1;
else L=mid+1;
}
printf("%lld\n",ans);
}
「UER #9」赶路
Solution
分治,设 \(\text{solve}(S,T,V)\) 表示从 \(S\) 走到 \(T\) 之间要经过的点集是 \(V\)。
从 \(V\) 里随便找个点,然后将 \(S\) 与这个点连接起来,这条直线将平面分为两个部分,这样就是子问题了。
Code
const int N=500;
int n,x[N+10],y[N+10];
vector<int> id;
int check(int a,int b,int c) {
ll K=1ll*(x[b]-x[a])*(y[c]-y[a])-1ll*(x[c]-x[a])*(y[b]-y[a]);
if(K>0) return 1;return 0;
}
void solve(int s,int t,vector<int> v) {
if(v.size()==0) return;
vector<int> a[2];
for(int i=1;i<v.size();i++) a[check(s,v[0],v[i])].pb(v[i]);
int K=check(s,v[0],t);
solve(s,v[0],a[K^1]),printf("%d ",v[0]),solve(v[0],t,a[K]);
}
void solve() {
scanf("%d",&n);id.clear();
for(int i=1;i<=n;i++) scanf("%d %d",&x[i],&y[i]);
for(int i=2;i<n;i++) id.pb(i);
printf("1 ");
solve(1,n,id);
printf("%d\n",n);
}
int main() {
int T;scanf("%d",&T);
while(T--) solve();
}