题解:P11245 残雪
也许更烂的阅读体验
题意
是否存在一个由
转化
对于 01 串个数相等的问题,容易想到将其转化为在二维平面中走网格的问题,即每选择一个
这样的话,一个子串内
我们就成功将题意转化成了:从
贪心
然后你发现就做完了。
这个问题看起来就很可做,我们先考虑最优的走法是什么?
显然最开始在
草率的想一下,如果某一时刻我们走到了
延续上面的思路,我们尽量让不可走位置先进入数轴下面,直接贪心。先走到
建议考虑不可走位置的边界(挨着圆点的小叉),如果最后与 x 轴的交点大于零,那就可以。
发现不可走位置会跟着路径平移,也就是不可走位置的边界会复制我们走的路径,路径又需要贴着边界走,就是一个类似螺旋升天分形的过程。建议从
推广到
现在你闭着眼都知道边界是什么样的了,计算周期,小心处理最后接近 x 轴的一小段,你就做完了。
注意一些 Corner case。
附上打表器。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 2e4+5;
LL n,m,l,r;
char a[N][N];
int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
int T; scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld%lld",&l,&r,&n,&m);
if(n>m) swap(n,m);
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++) a[i][j]='c';
// if(n==0||m==0) puts("Yes");
queue<pair<LL,LL> > q;
q.push({n,m});
while(!q.empty())
{
LL x=q.front().first,y=q.front().second; q.pop();
a[x][y]='a';
for(int i=l;i<=r;i++)
{
if(x-i<0||y-i<0) break;
a[x-i][y-i]='b';
}
if(x-1>=0&&a[x-1][y]!='b'&&(!(y>=m-l&&x==n-l+1))) q.push({x-1,y});
else if(y-1>=0&&a[x][y-1]!='b') q.push({x,y-1});
}
if(a[0][0]=='a') puts("Yes");
else puts("No");
for(int i=n;i>=0;i--)
{
for(int j=0;j<=m;j++) printf("%c ",a[i][j]); putchar('\n');
}
putchar('\n');
}
return 0;
}
AC record