XMU2018摸底测试 五子棋

64 篇文章 3 订阅
44 篇文章 0 订阅

五子棋

Description

嘿嘿嘿同学很喜欢下五子棋。有一天,他在网络上发现了一个N \times MN×M 的棋盘,这个棋盘有N行,M列,棋盘上只有黑子和空格。嘿嘿嘿同学想要知道,在其中一个空格上放置上一个黑子,会使得五子连珠的个数发生怎样的变化

我们所认为的五子连珠为横竖和两个斜对角线共4个方向,并且若多余五子成一条线,也只视为一个五子连珠。
有交叉的五子连珠互不影响计算。

例如:
下面这种情况在X处填入黑子后视为增加一个五子连珠:

     
     
  X   
     
     
     

在X处填入黑子后视为增加两个五子连珠:

     
     
X
     
     
     

在X处填入黑子后视为减少两个五子连珠:

          
          
          
          
          
X
          
          
          
          
          

Format

Input

输入的第一行为两个正整数N,M (0 < N,M <= 100)
接下来N行,每行M个数字,0或1,0表示空格,1表示黑子
在接下来1行两个正整数x,y(0 < x <= N, 0 < y <= M),表示询问若在(x,y)处放上黑子,五子连珠的个数会发生怎样的变化。题目保证输入的位置为空格。

Output

输出一个整数,表示若在(x,y)处放上黑子后,整个棋盘上五子连珠的变化情况,正数表示增加,负数表示减少,0表示不变

Sample 1

Input

5 5
1 0 1 0 0
0 0 0 0 0 
0 1 1 0 0
0 1 1 1 0 
0 1 1 0 1
2 2

Output

1

Sample 2

Input

5 5
1 0 1 0 0
1 1 0 1 1 
0 1 1 0 0
0 1 1 1 0 
0 1 1 0 1
2 3

Output

2

Limitation

1s, 1024KiB for each test case.

Hint

Source

Vijos Original






题目链接:

    https://www.vijos.org/d/XMU_ACM/p/5a9a0642d3d8a1371223e280

题目大意

    对于给定的五子棋棋盘,再下一枚棋子之后,五子连珠数量的变化情况
题目思路

    【模拟】

    解答该题的重点在于,如何判断5子连珠的变化,下面提供一种可行的方

法:
    对于题目给定的空白的格子X(未落子)
    在这个格子相邻的8个方向中,寻找每个方向上的未落子前的连续黑子个数
    这样得到了X八个方向上原先的黑子数目,接着分情况讨论
    考虑在一条直线上的两个方向(上和下、左和右,左上和右下、左下和右上)
    分别有三种情况:
    1.下完黑子后五子连珠个数从0变成1
    2.下完黑子后五子连珠个数保持1或0不变
    3.下完黑子后五子连珠个数由2变为1
    四个方向分开考虑,即可得到最终的答案


#define _CRT_SECURE_NO_WARNINGS
/****************************************************

Author : Coolxxx
Copyright 2018 by Coolxxx. All rights reserved.
BLOG : http://blog.csdn.net/u010568270

****************************************************/
#include<bits/stdc++.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define mem(a,b) memset(a,b,sizeof(a))
#define N 104
const double EPS = 1e-8;
const int J = 10;
const int MOD = 1000000007;
const int MAX = 0x7f7f7f7f;
const int inf = 100;
using namespace std;
int n, m, lll, ans, cas;
int ma[N][N];
int l[N][N][8];
int dx[]={-1,-1,-1,0,1,1,1,0};
int dy[]={-1,0,1,1,1,0,-1,-1};
int main()
{
#ifndef ONLINE_JUDGE
	//freopen("1.txt", "r", stdin);
	//freopen("2.txt", "w", stdout);
#endif
	int i, j, k;
	int x, y, z;
	while (~scanf("%d%d", &n, &m) && n && m)
	{
		cas=1;
		mem(ma,0);
		mem(l,0);
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
			{
				scanf("%d",&ma[i][j]);
			}
		}
		for(k=0;k<8;k++)
		{
			for(i=1;i<=n;i++)
			{
				for(j=1;j<=m;j++)
				{
					if(ma[i][j])continue;
					x=i+dx[k],y=j+dy[k];
					while(x>0 && x<=n && y>0 && y<=m && ma[x][y])
						l[i][j][k]++,x=x+dx[k],y=y+dy[k];
				}
			}
		}
		while(cas--)
		{
			scanf("%d%d",&x,&y);
			ans=0;
			for(k=0;k<4;k++)
			{
				if(l[x][y][k]+l[x][y][k+4]>=4 && l[x][y][k]<5 && l[x][y][k+4]<5)ans++;
				if(l[x][y][k]>=5 && l[x][y][k+4]>=5)ans--;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}
/*
//

//
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值