前言
开始一脸茫然…后来偷看了大佬的博客感觉超级nice,推一波
传送门
个人理解
感觉大佬的博客已经讲解的非常详细了,输出的结果只要满足:
1)整个方阵关于j=i这条线对称,加减号相反,因为横轴纵轴都表示玩家,2:4="+“相当于2赢了4,但相同,4:2=”-"相当于4输给了2,所以对称相反
2)对于使用策略2的玩家所在的行每行必然有至少一个“+”;其余自由分配“-”;
…大佬讲得太详细,上一遍AC的代码解释吧
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char s[55];
char res[55][55];
int main() {
int t;
cin>>t;
while(t--) {
int n;
cin>>n;
int one=0,two=0;
for(int i=0; i<n; i++) {
cin>>s[i];
if(s[i]=='1') {
one++;
} else {
two++;
}
}//记录个数
if(two==1||two==2) {
cout<<"NO"<<endl;
continue;
}//不符合情况
memset(res,0,sizeof(res));
for(int i=0; i<n; i++) {//对方阵初始化,填上"="
for(int j=0; j<n; j++) {
if(s[i]=='1') {
res[i][j]='=';
res[j][i]='=';
}
if(j==i) {
res[i][j]='X';
}
}
}
for(int i=0; i<n; i++) {
int flag=0;//判断这行是否已经有了"+",0-没有
for(int j=0; j<n; j++) {
if(s[i]=='2') {
if(res[i][j]=='+'){//遍历到"+",则表示有+了,
flag=1;//令flag=1,表示后面可以填"-"
}
if(!res[i][j]&&flag==0){//没有"+",填上一个"+"
res[i][j]='+';
res[j][i]='-';//反对称
flag=1; //已经填上"+",则表示有,flag=1;
}
if(!res[i][j]&&flag==1){//有"+",表示后面可以填"-"
res[i][j]='-';
res[j][i]='+';//记得对称位置填上相反
}
}
}
}
cout<<"YES\n";
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<res[i][j];
}
cout<<endl;
}
}
}