持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
第三届辽宁省大学生程序设计竞赛——B-可莉的五子棋
B-可莉的五子棋
题目描述
可莉最近沉迷于蒙德五子棋,她在棋盘上放了一些棋子。
蒙德五子棋的规则如下。
给定一个n*m的棋盘。棋盘上有两种棋子“1”和“2”,其中每种棋子分别计算得分。
假如相同种类的五个棋子连成相邻的一行,一列,或斜对角线的情况,每有五个这样的棋子,该种类棋子加1分。
可莉已经把她的棋子都摆在了棋盘上。
但是可莉不太聪明的样子,她希望你,聪明的旅行者,告诉她,她两种棋子的得分。
输入描述:
第一行两个整数n,m,表示棋盘的大小。
接下来输入一个n*m的矩阵,表示棋盘。
“1”,“2”表示该位置有对应的棋子。
“0”表示该位置没有棋子。
输出描述:
一行2个整数,以空格隔开,表示“1”,“2”两种棋子各自的得分。
输入
20 20
10202022021000221222
22111122221221101010
11211001210010001210
02222120211010112111
21220011111022120012
00111101111212221010
22122012211221212111
22102022221121110211
20222121122221221121
10012221102212201222
12110201221022101111
02212201100112112111
22111222202221211110
12112222222122102121
21021120121212010221
10222001121022022112
11111201112100221021
12112102021200111100
21021021011222222202
12021221122012111212
输出
10 12
备注:
1<=n,m<=1000
可莉只是懒的算,才...才不是算不出来!
问题解析
对于当前的棋子,我们可以把它看作是4个来自不同且不对立的方向的延申。
比如对于坐标(x,y)的棋子,我们可以把它看作是(x,y-1)、(x-1,y-1)、(x-1,y)、(x-1,y+1)这四个方向的延申(如图,黄色格子可以是我们当前的格子)
我们设置三维状态转移数组f,f[x] [y] [z]的意思是,对于位置(x,y)处的棋子,来自方向z的连续棋子数为f[x] [y] [z]。
当方向z的棋子与(x,y):
- 相同时,有:f[x] [y] [z]=f[x+dx[z]] [y+dy[z]] [z]+1;
- 不相同时,有:f[x] [y] [z]=1;
当f[x] [y] [z]>=5 时,当前棋子得分+1。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 1050;
int a[N][N], f[N][N][5];
int dx[8] = { 0,-1,-1,-1,0,1,1,1 }, dy[8] = { -1,-1,0,1,1,1,0,-1 };
void solve()
{
int n, m;
cin >> n >> m;
string s;
unordered_map<int, int>mymap;
for (int i = 1; i <= n; i++)
{
cin >> s;
for (int j = 1; j <= m; j++)
{
a[i][j] = s[j-1] - '0';
if (a[i][j] == 0)continue;
for (int k = 0; k < 4; k++)
{
int x = i + dx[k], y = j + dy[k];
if (a[x][y] == a[i][j])
{
f[i][j][k] = f[x][y][k] + 1;
if (f[i][j][k] >= 5)
{
mymap[a[i][j]]++;
}
}
else
{
f[i][j][k] = 1;
}
}
}
}
cout << mymap[1] << " " << mymap[2];
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}