题目大意
两人在n行m列的棋盘上玩五子棋,但他们都不想赢。因此,他们想将棋盘下满,但不分出胜负(也就是双方都没有连续的五子出现)。
规则:黑棋先落子,黑白棋交替落子。黑棋用字符’x'代表,白棋用字符'o'代表。
设计程序,给出将棋盘下满且平局的落子方式。
思路
由于黑棋先手,'x'的个数要么跟'o'相等,要么多1个。
对于每一行,"oooo"和"xxxx"交替出现,最后不满四个的,截取(m mod 4)个留下,相邻行之间的字符交替。那么,每两行,所含'o'和'x'的个数是相等的,且这样的排列方式不会形成五子相连。
例:n=4,m=7
xxxxooo
ooooxxx
xxxxooo
ooooxxx
现在,还有一个问题——如果n为奇数怎么办?这时候就需要特殊处理。前面n-1行按照上面的方法进行处理。第n行以'x'开头,然后"xoxoxox..."这样交替,而n为奇数,这样可以保证'x'比'o'多一个。
代码
#include <iostream>
#include <map>
using namespace std;
char ans[1005][1005];
int main()
{
map<char, char> oppo;
oppo['x'] = 'o';
oppo['o'] = 'x';
char ch[2] = {'o', 'x'};
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
int flag = 0;
if (n & 1)
{
flag = 1;
for (int i = 1; i <= m; ++i)
{
ans[n][i] = ch[i & 1];
}
--n;
}
/*for(int i=1;i<=m;++i)
{
cout<<ans[n+1][i];
}*/
char c = 'o';
ans[0][0] = 'o';
for (int i = 1; i <= n; ++i)
{
if (i != 1) c = oppo[ans[i - 1][1]];
ans[i][0] = oppo[ans[i - 1][0]];
for (int j = 1; j <= m; j += 4)
{
for (int k = 0; k < 4; ++k)
{
ans[i][j + k] = c;
}
c = oppo[c];
}
if (m % 4 == 0) continue;
int pre = m / 4 * 4;
c = oppo[ans[i][pre]];
for (int j = pre + 1; j <= m; ++j)
{
ans[i][j] = c;
}
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
cout << ans[i][j];
}
cout << endl;
}
if (flag)
{
for (int j = 1; j <= m; ++j)
{
cout << ans[n + 1][j];
}
cout << endl;
}
}
return 0;
}