Omkar and Duck
题目大意
这是一个交互题,
你先给出一个矩阵,然后输入权值,这个权值是矩阵中(1,1)点到(n,n)点的路径上的权值和。让你输出这个路径。
所以要保证每种走法的路径权值和都不一样。
题解
做的时候想到了,可能的权值是0~x (x是走法的数量)。
但是不会构造,,画了好多,没构造出来。。
其实只要让x步后所能到达每个点的权值范围都不一样即可。
x步能到达的点就是左下到右上对角线上的点。,
所以只要让从1,1点到每个对角线上的每个点的权值范围不同即可。
这样的话,就可以一个斜线一个斜线看,
在每一个斜线上当前的范围得从上一个的范围+1开始。
代码:
#include<algorithm>
#include<iostream>
#include <cstdio>
#include <string>
#include <queue>
#include <cstring>
#include <map>
#include <stack>
#include <bitset>
#include <set>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef unsigned long long ull;
typedef unordered_set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void tempwj(){
freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){
return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){
a %= mod;ll ans = 1;while(b > 0){
if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{
bool operator()(const pii & a, const pii & b){
return a.second > b.second;}};
int lb(int x){
return x & -x;}
//friend bool operator < (Node a,Node b) 重载
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const int maxn = 2e5+10;
const int M = 1e6 + 2;
ll a[30][30];
pll pp[30][30];
int main()
{
int n;
scanf("%d",&n);
pp[1][1] = mkp(0,0);
for (int i = 3; i <= 2 * n; i ++ )
{
ll per = 0;
for(int j = 1; j <= n; j ++ )
{
for (int k = 1; k <= n; k ++ )
{
if(j + k != i)
continue;
ll maxx = 0, minn = INF;
if(j - 1 >= 1)
{
maxx = max(maxx,pp[j - 1][k].sd);
minn = min(minn,pp[j - 1][k].st);
}
if(k - 1 >= 1)
{
maxx = max(maxx,pp[j][k - 1].sd);
minn = min(minn,pp[j][k - 1].st);
}
pp[j][k] = mkp(per, per + maxx - minn);
a[j][k] = per - minn;
per = pp[j][k].sd + 1;
}
}
}
for (int i =1; i <= n; i ++ )
{
for (int j = 1; j <= n; j ++ )
printf("%lld ",a[i][j]);
printf("\n");
fflush(stdout);
}
// for (int i= 1; i <= n; i ++ )
// {
// for (int j = 1; j <= n; j ++ )
// {
// printf("%lld %lld ",pp[i][j].st,pp[i][j].sd);
// }
// printf("\n");
// }
int q;
scanf("%d",&q);
std::vector<pii> vv;
while(q -- )
{
vv.clear();
ll s;
scanf("%lld",&s);
int x = n, y = n;
s -= a[n][n];
vv.pb(mkp(n,n));
while(x > 1 || y > 1)
{
if(x > 1 && s >= pp[x - 1][y].st && s <= pp[x - 1][y].sd)
{
s -= a[x - 1][y];
vv.pb(mkp(x - 1,y));
x -- ;
}
else
{
s -= a[x][y - 1];
vv.pb(mkp(x, y - 1));
y -- ;
}
}
for (int i= vv.size() - 1; i >= 0; i -- )
{
printf("%d %d\n",vv[i].st,vv[i].sd);
fflush(stdout);
}
}
}