[COTS/CETS 2020] 辣椒 Sadnice 题解
Izborne Pripreme 最喜欢出的组合构造。下文中使用了官方题解内的部分图片。
由于绳索形成了该网格图的一个生成树,每切断一条边连通块的个数就会
试图求出答案的一个下界:总共有
首先考虑一个基本结构:令辣椒的行、列编号从
接着考虑将奇数行的辣椒向上 / 下 / 右连边以形成生成树,由于每一“行”(这里带引号的“行”指绳索的行)最多放
即对于奇数行,从上一个奇数行往上 / 下连边的最后一列往后一列开始,向上依次连
观察到上面往右连的绳索也是尽量错开的,又由于
放代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
int n,m,k; cin>>n>>m,k=(n*m-1)/(n+m)+1;
// 这里 k 为上文所述的 (L - 1)
vector s(n<<1|1,string(m*3+1,32));
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
s[i<<1][j*3]='o';
auto connect=[&](int x,int y,int op){
if(op)s[(x<<1)+op][y*3]='|';
else s[x<<1][y*3+1]=s[x<<1][y*3+2]='-';
/* 连边:
* op = 0 表示向右连
* op = 1 表示向下连
* op = -1 表示向上连
*/
};
for(int i=0;i<=n;i++){
if(i&1){
for(int j=0;j<m;j++){
int x=((i-1)*k+j)%m;
if(j<k)connect(i,x,-1);
else if(j<k<<1&&i<n)connect(i,x,1);
else connect(i,x,0);
}
}
else for(int j=0;j<m;j++)
connect(i,j,0);
if(i<n)connect(i,m,1);
}
for(auto r:s)cout<<r<<'\n';
return 0;
}