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\),接下来考虑如何在线性时间内判定,以下是判定方法:

  1. 如果 \(\text{dist}(1,u)+\text{dist}(u,n)\le a+x\),那么一个点是好点:这是因为如果时刻 \(a\) 通知了,那么如果不满足这个条件,是怎样也赶不到的。
  2. 考虑扩展好点,如果有一条边 \((u,v,w)\) 并且 \(w+\text{dist}(v,n)\le x\),那么 \(v\) 与这条边均是好的:这是因为如果正在穿越这条边是通知了,那么拖延的时间一定 \(\le x\)
  3. 将好边与好点的导出子图建出,然后这个子图如果有环,那么可以摸鱼一直到通知。
  4. 否则,导出子图是一个 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]&&deg[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();
}
posted @ 2022-01-26 21:44  cnyz  阅读(735)  评论(0编辑  收藏  举报