一,思路:对于这题其实很简单,我们只需要按照要求,将每个横排按规则设置好(当然最左上角那个肯定是所有数的最小的那个,不然肯定构造不了),然后遍历数组看竖直方向上的数是否满足规则和该数是否存在。
二,代码:
#include <iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<vector>
using namespace std;
const int N=510,M=1e9+7;
typedef long long ll;
typedef pair<int,int> pii;
ll arr[N][N];
void Solved() {
int n,c,d;
cin>>n>>c>>d;
map<int,int> m;
int mi=1e9;
for(int i=1;i<=n*n;i++){
int x;
cin>>x;
mi=min(mi,x);
m[x]++;
}
arr[1][1]=mi;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
//构造数组(只按横向规则)
if(j==1&&i!=1) arr[i][j]=arr[i-1][j]+c;
if(j!=1) arr[i][j]=arr[i][j-1]+d;
}
}
int flag=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
//判断该数是否存在
if(m[arr[i][j]]<=0){
cout<<"No"<<endl;
return;
}
//将已经利用过的数丢弃,每个数只能用一次
m[arr[i][j]]--;
//判断竖直方向上是否符合规则
if(i!=1&&arr[i-1][j]!=arr[i][j]-c){
cout<<"No"<<endl;
return;
}
}
}
cout<<"Yes"<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) {
Solved();
}
return 0;
}