牛客小白月赛6 E 对弈 思维

2023-01-08,,

链接:https://www.nowcoder.com/acm/contest/136/E
来源:牛客网

题目描述

善弈者谋势,不善弈者谋子。

                                        ——《弈林新编》

蒟蒻HtBest与神犇WHZ下棋(五子棋),HtBest执黑棋,WHZ执白棋。由于HtBest天资愚笨,不会判断输赢,所以需要你帮他开发一个判断五子棋输赢的程序。

输入描述:

第一行有2个正整数n,m,分别表示棋盘大小(n*n)和对弈步数。
接下来m行,每行两个正整数x

i

,y

i

 ,表示对弈者下棋的坐标,第2、4、6…行是HtBest下的棋子,第3、5、7…行是WHZ下的棋子。

输出描述:

第一行一个字符串s 和一个正整数num ,用空格隔开,分别表示对弈的胜负结果和该结果出现时的步数,如果HtBest胜则s=“HtBest”,num为HtBest胜利时的步数(为偶数),如果WHZ胜则s=“WHZ”,num为WHZ胜利时的步数(为奇数),如果对弈m步后胜负仍未定,则s=“UNK”,num=m。
提示:当棋盘上第一次有五个子连续排列(横竖斜都可)时,胜负已定。在这之后,两人有可能仍继续落子。

<!--
-->

输入例子:
10 20
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2
6 1
6 2
7 1
7 2
8 1
8 2
9 1
9 2
10 1
10 2
输出例子:
HtBest 9

-->

示例1

输入

复制

10 20
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2
6 1
6 2
7 1
7 2
8 1
8 2
9 1
9 2
10 1
10 2

输出

复制

HtBest 9

说明

在第9步时,HtBest获胜,当前局面:

示例2

输入

复制

10 27
8 6
9 4
2 1
7 5
4 7
8 4
4 3
5 4
10 3
5 5
9 7
9 5
3 4
6 3
5 10
1 5
9 2
6 5
5 7
1 4
2 5
8 5
1 3
3 2
8 3
2 6

输出

复制

WHZ 22

说明

在第22步时,WHZ获胜,当前局面:

示例3

输入

复制

10 1
1 1

输出

复制

UNK 1

说明

下一手后,胜负未分。

备注:

对于100%的测试数据:
1 ≤ n ≤ 1000
1 ≤ m ≤ 100000 发现小白赛后面的题目好水呀。。
这题目比赛的时候竟然没有多少人做。。
卡在前面的题目挺难受的。。
分析:在每次HtBest或者WHZ下棋的时候,判断下他下的这布棋是否可以获胜
  获胜的条件,遍历行,列,两种斜线看是否有五个棋子,写几个for循环判断
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ls (r<<1)
#define rs (r<<1|1)
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 1e6+10;
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
ll n, m, mapn[1005][1005];
bool ok( ll x, ll y ) {
ll cnt = 1;
//下面两个循环判断行是否有五颗棋子
for( ll i = x-1; i >= 1; i -- ) {
if( mapn[i][y] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
for( ll i = x+1; i <= n; i ++ ) {
if( mapn[i][y] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
cnt = 1;
//下面两个循环判断列是否有五颗棋子
for( ll i = y-1; i >= 1; i -- ) {
if( mapn[x][i] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
for( ll i = y+1; i <= n; i ++ ) {
if( mapn[x][i] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
cnt = 1;
//下面两个循环判断左斜线是否有五颗棋子
for( ll i = x-1, j = y-1; i >= 1 && j >= 1; i --, j -- ) {
if( mapn[i][j] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
for( ll i = x+1, j = y+1; j <= n && i <= n; i ++, j ++ ) {
if( mapn[i][j] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
cnt = 1;
//下面两个循环判断右斜线是否有五颗棋子
for( ll i = x-1, j = y+1; i >= 1 && j <= n; i --, j ++ ) {
if( mapn[i][j] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
for( ll i = x+1, j = y-1; i <= n && j >= 1; i ++, j -- ) {
if( mapn[i][j] == mapn[x][y] ) {
cnt ++;
} else {
break;
}
if( cnt >= 5 ) {
return true;
}
}
return false;
}
int main() {
ios::sync_with_stdio(0);
cin >> n >> m;
memset(mapn,0,sizeof(mapn));
bool flag = false;
for( ll i = 1, x, y; i <= m; i ++ ) {
cin >> x >> y;
if(i&1) {
mapn[x][y] = 1;
} else {
mapn[x][y] = 2;
}
if(!flag) {
if(ok(x,y)) {
if(i&1) {
cout << "HtBest " << i << endl;
} else {
cout << "WHZ " << i << endl;
}
flag = true;
}
}
}
if(!flag) {
cout << "UNK " << m << endl;
}
return 0;
}

  

牛客小白月赛6 E 对弈 思维的相关教程结束。