题解:AT_agc077_e [AGC077E] Hamiltonian Path Inversion
更好的阅读体验
?????????被打的措手不及。
我们需要解决这样一个问题:构造一个
首先考虑假设我们现在有一个 01 串
那么我们为了方便处理,我们希望,对于相邻的
那么我们考虑标记
- 如果这个
01 中的1 不是被标记区间中的最后一个1 ,那就可以看作,被标记区间的位置不变,然后区间中的0 向后移动一个位置,如0000\color{red}111\color{blue}0\color{red}11\color{black}00 \to 0000\color{red}1111\color{blue}0\color{red}1\color{black}00 - 如果这个
01 中的1 是呗标记区间中的最后一个1 ,那么操作后所有1 形成了一个连续段,那么这时标记区间中就会向左移动一位,如0000\color{red}111101\color{black}00 \to 000\color{blue}011111\color{black}000
这启发我们,我们可以将
考虑我们最终的路径是长什么样的:应该是在外圈走一些
由标记区间中
那么当
假设
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
int h,w,q,n,c1;
vector<pair<int,int> > walk_out1(int x,int y,int k)
{
vector<pair<int,int> > ret;
for(int i=1;i<=k;i++)
{
ret.push_back({x,y});
if(x==1&&y>1)y--;
else if(y==1&&x<h)x++;
else if(x==h&&y<w)y++;
else if(y==w&&x>1)x--;
}
return ret;
}
vector<pair<int,int> > walk_out2(int x,int y,int k)
{
vector<pair<int,int> > ret;
for(int i=1;i<=k;i++)
{
ret.push_back({x,y});
if(x==h&&y>1)y--;
else if(y==w&&x<h)x++;
else if(x==1&&y<w)y++;
else if(y==1&&x>1)x--;
}
return ret;
}
vector<pair<int,int> > walk_in(int x,int y,int k)
{
vector<pair<int,int> > ret;
for(int i=1;i<=k;i++)
{
ret.push_back({x,y});
if(x==2&&y>2)y--;
else if(y==2&&x<h-1)x++;
else if(x==h-1&&y<w-1)y++;
else if(y==w-1&&x>2)x--;
}
return ret;
}
void get_out(int &ix,int &iy,int &ox,int &oy)
{
if(ix==ox&&ix==2)ix--,ox--;
else if(ix==ox&&ix==h-1)ix++,ox++;
else if(iy==oy&&iy==2)iy--,oy--;
else if(iy==oy&&iy==w-1)iy++,oy++;
}
void solve()
{
scanf("%d",&n);
int fr=h*w-c1-n/c1-1,num=n%c1;
auto in=walk_in(2,2,num+2);
int x_out=in.back().first,y_out=in.back().second;
in=walk_in(x_out,y_out,c1+1);
int x_in=in.back().first,y_in=in.back().second;
reverse(in.begin(),in.end());
get_out(x_in,y_in,x_out,y_out);
auto out1=walk_out2(x_in,y_in,fr);
reverse(out1.begin(),out1.end());
auto out2=walk_out1(x_out,y_out,h*w-c1-1-fr);
for(auto i:out1)printf("%d %d\n",i.first,i.second),fflush(stdout);
for(auto i:in)printf("%d %d\n",i.first,i.second),fflush(stdout);
for(auto i:out2)printf("%d %d\n",i.first,i.second),fflush(stdout);
}
void construct()
{
for(int i=1;i<=w;i++)putchar('0');
putchar(10),fflush(stdout),printf("00");
for(int i=3;i<w;i++)putchar('1');
printf("0\n"),fflush(stdout),putchar('0');
for(int i=2;i<w;i++)putchar('1');
printf("0\n"),fflush(stdout);
for(int i=1;i<=w;i++)putchar('0');
putchar(10),fflush(stdout),c1=2*(w-2)-1;
}
main()
{
scanf("%d%d%d",&h,&w,&q),construct();
while(q--)solve();
return 0;
}