P8303 [CoE R4 C] 网格 题解
Sakura_xyz · · 题解
直接模拟即可。
分析
我们注意到这样一件事情,对于一张网格图来说,确定两个邻角到每个点的曼哈顿距离就可以确定整张图的结构。
规定网格图规模为
例如,设图的左上角为
我们构造两条路径:
1.从左上角
2.从右下角
可以发现,两条路径的长度分别为
首先,无论
现在问题就转化成了在
我们先询问
并且,我们确定了
现在,我们根据已知条件,求出点
设:
不妨设
我们观察到,满足
不妨设
注意到
另外,我们观察到,有很多情况需要特判。
定义一个点的度数为与其距离为
首先,只有一个点的时候直接判。
然后,我们发现,若点
同理,若点
以上是我花
AC 代码
#include<iostream>
#include<cstdio>
#include<utility>
#include<vector>
#include<algorithm>
#define MAXN 100005
#define fi first
#define se second
using namespace std;
int n,a1[MAXN],a2[MAXN],a3[MAXN];
void Ask(int * a,int x){
cout << x << endl;
for(int i=1;i<=n;i++) cin >> a[i];
}
int X,Y,Z,l,c,x_1,y_1;
inline int dis_1(int x) { return a1[x]; }
inline int dis_X(int x) { return a2[x]; }
inline int dis_Y(int x) { return l+c-2-a2[x]; }
inline int dis_Z(int x) { return a3[x]; }
inline int Abs(int x) { return x>0?x:-x; }
inline int get_d(int * a){
int ret=0;
for(int i=1;i<=n;i++) ret+=(a[i]==1);
return ret;
}
void solve_1(){
vector <int> a(n,0);
a[0]=1;
for(int i=1;i<=n;i++) a[a1[i]]=i;
cout << 0 << endl;
cout << 1 << ' ' << n << endl;
for(int i=0;i<n;i++) cout << a[i] << ' ';
cout << endl;
}
void get_ans(int pos_1){
for(int i=1;i<=n;i++) if(a2[i]>=a2[Y]) Y=i;
int sum_lc=dis_X(Y)+2;
for(int i=1;i<=n;i++){
if((!(n%i))&&i+n/i==sum_lc){
l=i; c=n/i; break;
}
}
int t1=0,t2=0;
for(int i=1;i<=n;i++){
if(dis_1(i)+dis_X(i)==dis_X(pos_1)) t1++;
if(dis_1(i)+dis_Y(i)==dis_Y(pos_1)) t2++;
}
for(int i=1;i<=l;i++){
for(int j=1;j<=c;j++){
if(i+j==dis_1(X)+2&&i*j==t1&&(l-i+1)*(c-j+1)==t2){
x_1=i,y_1=j;
break;
}
}
}
vector <int> ld,ru;
for(int i=1;i<=n;i++){
if(dis_X(i)==l-1&&dis_1(i)==Abs(l-x_1)+Abs(y_1-1)){
ld.push_back(i);
}
if(dis_X(i)==c-1&&dis_1(i)==Abs(1-x_1)+Abs(c-y_1)){
ru.push_back(i);
}
}
vector < vector <int> > a(l,vector <int> (c,0));
if(Z){
if(dis_X(Z)==l-1){
for(int i=1,tx,ty;i<=n;i++){
ty=(dis_Z(i)+dis_X(i)-dis_X(Z)+2)/2;
tx=dis_X(i)-ty+2;
a[tx-1][ty-1]=i;
}
cout << 0 << endl;
cout << l << ' ' << c << endl;
for(int i=0;i<l;i++){
for(int j=0;j<c;j++){
cout << a[i][j] << ' ';
}
cout << endl;
}
}
else{
for(int i=1,tx,ty;i<=n;i++){
tx=(dis_Z(i)+dis_X(i)-dis_X(Z)+2)/2;
ty=dis_X(i)-tx+2;
a[tx-1][ty-1]=i;
}
cout << 0 << endl;
cout << l << ' ' << c << endl;
for(int i=0;i<l;i++){
for(int j=0;j<c;j++){
cout << a[i][j] << ' ';
}
cout << endl;
}
}
return;
}
if(ld.size()==1){
Ask(a3,ld[0]),Z=ld[0];
for(int i=1,tx,ty;i<=n;i++){
ty=(dis_Z(i)+dis_X(i)-dis_X(Z)+2)/2;
tx=dis_X(i)-ty+2;
a[tx-1][ty-1]=i;
}
cout << 0 << endl;
cout << l << ' ' << c << endl;
for(int i=0;i<l;i++){
for(int j=0;j<c;j++){
cout << a[i][j] << ' ';
}
cout << endl;
}
}
else{
Ask(a3,ru[0]),Z=ru[0];
for(int i=1,tx,ty;i<=n;i++){
tx=(dis_Z(i)+dis_X(i)-dis_X(Z)+2)/2;
ty=dis_X(i)-tx+2;
a[tx-1][ty-1]=i;
}
cout << 0 << endl;
cout << l << ' ' << c << endl;
for(int i=0;i<l;i++){
for(int j=0;j<c;j++){
cout << a[i][j] << ' ';
}
cout << endl;
}
}
}
void solve_2(){
int p;
for(int i=1;i<=n;i++){
if(a1[i]==1) { p=i; Ask(a2,p); break; }
}
if(get_d(a2)>=3){
swap(a2,a1); X=1;
get_ans(p);
}
else if(get_d(a2)==1){
vector <int> a(n,0);
a[0]=p;
for(int i=1;i<=n;i++) a[a2[i]]=i;
cout << 0 << endl;
cout << 1 << ' ' << n << endl;
for(int i=0;i<n;i++) cout << a[i] << ' ';
cout << endl;
}
else{
for(int i=1;i<=n;i++) if(a2[i]>=a2[Z]) Z=i;
Ask(a3,Z);
if(get_d(a3)==1){
vector <int> a(n,0);
a[0]=Z;
for(int i=1;i<=n;i++) a[a3[i]]=i;
cout << 0 << endl;
cout << 1 << ' ' << n << endl;
for(int i=0;i<n;i++) cout << a[i] << ' ';
cout << endl;
}
else{
swap(a1,a2);
get_ans(p);
}
}
}
void solve(){
X=Y=Z=l=c=x_1=y_1=0;
cin >> n;
Ask(a1,1);
if(get_d(a1)==0){
cout << 0 << endl;
cout << 1 << ' ' << 1 << endl;
cout << 1 << endl;
return;
}
if(get_d(a1)==1) return solve_1();
if(get_d(a1)==2) return solve_2();
for(int i=1;i<=n;i++) if(a1[i]>=a1[X]) X=i;
Ask(a2,X);
get_ans(1);
}
int main(){
int T; cin >> T;
while(T--) solve();
return 0;
}