P7515 [省选联考 2021 A 卷] 矩阵游戏
这道题目考场上面一点思路没有,虽然尝试了一下 \(75pts\) ,但最后就打了个暴力。。。
考出来后听到同学说什么最短路,差分约束?直接蒙圈,跟我说网络流还有点道理,这就不是很懂了。。。
然后现在决定来写一下这道神仙题。
题解
我们发现只要确定了第一行第一列,一定可以确定整一个矩阵。
\[\begin{matrix}
a_1 & a_2 & a_3 & a_4 \\
a_5 & b_{1,1}-a_1-a_2-a_5 & b_{1,2}-b_{1,1}+a_1-a_3+a_5 & b_{1,3}-b_{1,2}+b_{1,1}-a_1-a_4-a_5 \\
a_6 & b_{2,1}-b_{1,1}+a_1+a_2-a_6 & b_{2,2}-b_{1,2}-b_{2,1}+b_{1,1}-a_1+a_3+a_6 & b_{2,3}-b_{2,3}-b_{1,3}+b_{1,2}+b_{2,1}-b_{1,1}+a_1+a_4-a_6 \\
a_7 & b_{3,1}-b_{2,1}+b_{1,1}-a_1-a_2-a_7 & b_{3,2}-b_{2,2}-b_{3,1}+b_{2,1}+b_{1,2}-b_{1,1}+a_1-a_3+a_7 & b_{3,3}-b_{3,2}-b_{2,3}+b_{1,3}+b_{2,2}+b_{3,1}-b_{1,2}-b_{2,1}+b_{1,1}-a_1-a_4-a_7 \\
\end{matrix}
\]
然后发现规律很好找,相当于每一个都变成了包含 \(a_1\) 和随机两个 \(a\) 的不等式。
我们现在干脆把一个位置中所有的 \(b_{i,j}\) 用一个变量 \(c_{i,j}\) 来代替,矩阵就变成了下面的这个。
\[\begin{matrix}
a_1 & a_2 & a_3 & a_4 \\
a_5 & c_{1,1}-a_1-a_2-a_5 & c_{1,2}+a_1-a_3+a_5 & c_{1,3}-a_1-a_4-a_5 \\
a_6 & c_{2,1}+a_1+a_2-a_6 & c_{2,2}-a_1+a_3+a_6 & c_{2,3}+a_1+a_4-a_6 \\
a_7 & c_{3,1}-a_1-a_2-a_7 & c_{3,2}+a_1-a_3+a_7 & c_{3,3}-a_1-a_4-a_7 \\
\end{matrix}
\]
我们发现我们现在遇到了两个问题:
- 每一个式子里都存在一个 \(a_1\) ,但是我们没有办法消去,我们需要实现对于 \(a_1\) 的枚举?
- 如果在确定 \(a_1\) 的情况下,对于一个位置存在的不等式,他的种类也有许多,我们不好直接使用。
对于第二个问题好像我有解决的方案,你考虑把一些位置变成负数,这样的话就可以满足一正一负的不等式了。
\[\begin{matrix}
a_1 & -a_2 & a_3 & -a_4 \\
a_5 & c_{1,1}-a_1+a_2-a_5 & c_{1,2}+a_1-a_3+a_5 & c_{1,3}-a_1+a_4-a_5 \\
-a_6 & c_{2,1}+a_1-a_2+a_6 & c_{2,2}-a_1+a_3-a_6 & c_{2,3}+a_1-a_4+a_6 \\
a_7 & c_{3,1}-a_1+a_2-a_7 & c_{3,2}+a_1-a_3+a_7 & c_{3,3}-a_1+a_4-a_7 \\
\end{matrix}
\]
这样就行了。
刚刚偷偷复习了一下差分约束。
然后感觉这个 \(a_1\) 消不掉啊。。。
我们发现可以把第一列全部换成和 \(a_1\) 的关系。
\[a_1+a_5=d_5\\
a_1+a_6=d_6\\
a_1+a_7=d_7\\
\begin{matrix}
a_1 & -a_2 & a_3 & -a_4 \\
d_5-a_1 & c_{1,1}+a_2-d_5 & c_{1,2}-a_3+d_5 & c_{1,3}+a_4-d_5 \\
a_1-d_6 & c_{2,1}-a_2+d_6 & c_{2,2}+a_3-d_6 & c_{2,3}-a_4+d_6 \\
d_7-a_1 & c_{3,1}+a_2-d_7 & c_{3,2}-a_3+d_7 & c_{3,3}+a_4-d_7 \\
\end{matrix}
\]
然后就好像可以搞差分约束了。
被判负环搞没了。
\(\huge{😭😭😭😭😭😭😭😭😭😭😭😭😭😭}\)
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=305;
int n,m,a[N][N],b[N][N],c[N][N],d[N<<1],mp[N<<1][N<<1];
deque<int> q;int tag[N<<1],cnt[N<<1];
inline int read(){
char c=getchar();int x=0;
while(c<'0'||'9'<c) c=getchar();
while('0'<=c&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
void init(){
memset(cnt,0,sizeof(cnt));
memset(tag,0,sizeof(tag));
while(!q.empty()) q.pop_back();
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n+m;++i){
for(int j=1;j<=n+m;++j)
mp[i][j]=1e18+7;
}
for(int i=1;i<n;++i){
for(int j=1;j<m;++j){
b[i][j]=read();
c[i][j]=b[i][j]-c[i-1][j]-c[i][j-1]-c[i-1][j-1];
}
}
for(int i=1;i<n;++i){
for(int j=1;j<m;++j){
if((i^j)&1) mp[i+m][j+1]=c[i][j],mp[j+1][i+m]=1e6-c[i][j];
else mp[i+m][j+1]=1e6-c[i][j],mp[j+1][i+m]=c[i][j];
}
}
for(int i=1;i<n;++i){
if(i&1) mp[1][i+m]=1e6,mp[i+m][1]=0;
else mp[1][i+m]=0,mp[i+m][1]=1e6;
}
for(int i=1;i<=m;++i){
if(i&1) mp[n+m][i]=1e6,mp[i][n+m]=0;
else mp[n+m][i]=0,mp[i][n+m]=1e6;
}
for(int i=1;i<n+m;++i) d[i]=1e18+7;
d[n+m]=0,q.push_back(n+m),tag[n+m]=true,cnt[n+m]=0;
while(!q.empty()){
int u=q.front();q.pop_front(),tag[u]=false;
for(int v=1;v<=n+m;++v){
if(d[v]<=d[u]+mp[u][v]) continue;
d[v]=d[u]+mp[u][v],cnt[v]=cnt[u]+1;
if(cnt[v]>n+m) return printf("NO\n"),void();
if(!tag[v]){
if(q.empty()) q.push_back(v);
else if(d[v]<d[q.front()]) q.push_front(v);
else q.push_back(v);
tag[v]=true,cnt[v]++;
}
}
}
for(int i=1;i<=m;++i) a[1][i]=(i&1)?d[i]:-d[i];
for(int i=1;i<n;++i) a[i+1][1]=(i&1)?d[i+m]-d[1]:d[1]-d[i+m];
for(int i=1;i<n;++i){
for(int j=1;j<m;++j)
a[i+1][j+1]=b[i][j]-a[i+1][j]-a[i][j+1]-a[i][j];
}
printf("YES\n");
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j)
printf("%lld ",a[i][j]);
printf("\n");
}
}
signed main(){
int T;cin>>T;
while(T--) init(),solve();
return 0;
}

浙公网安备 33010602011771号