Codeforces Round113(div .2) B. Chess Tournament
思路:
1:先说输出结果为NO的情况。当只有1个或者2个记号2时,输出NO,至于为什么是这两种情况,因为当记号2的个数>=2时,那么就一定可以形成下面所说的圈。
2:输出YES的情况。既然记号1是代表这个人一场都不输,那么对局有两种结果一种结果是=,一种结果是+。此时容易知道如果我们一碰到1便将他的任何对局结果都变成=,那么无论对手是记号是1还是2,都符合题意。而当某个人是记号2,需要他至少赢一场。那么我们可以将所有记号为2的下标存储起来,先存储的可以赢下他后一位存储的,后一位存储的可以赢下后后一位存储的,最后一位存储的可以赢下第一位存储的,形成了一个圈,此时可以满足所有为2的至少都赢了一局。而其他的对局则不需要管了,全部算成=就行了
代码如下
#include <bits/stdc++.h>
using namespace std;
char k[60][60];
int main()
{
int t;
vector<int> v;//用v来存储记号为2的下标
cin>>t;
while(t--)
{
int n;
char c;
cin>>n;
memset(k,'=',sizeof k);//将所有对局初始化为=
v.clear();//记得清除
for(int i=0;i<n;i++)
{
cin>>c;
k[i][i]='X';
if(c=='2')v.push_back(i);
}
if(v.size()==1||v.size()==2){cout<<"NO"<<endl;continue;}
cout<<"YES"<<endl;
for(int i=0;i<v.size();i++)
{
int j=v[i],h=v[(i+1)%v.size()];//为了满足记号为2的至少赢一把
k[j][h]='+';
k[h][j]='-';
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)cout<<k[i][j];
cout<<endl;
}
}
}