人工智能
时间限制: 1 Sec 内存限制: 128 MB
题目描述
人胖了就容易打瞌睡,打瞌睡又会导致长胖,这对小X的减重计划很不利,于是小X决定做点动脑子的事来抵御瞌睡虫的进袭,小X决定响应国务院的号召投身到人工智能的研究开发大潮中去,具体研究什么好呢?小X再三思考后决定开发国际象棋的人工智能软件,虽然国际象棋的软件已经能够战胜人类世界冠军了,但那是基于搜索的 AI(AI 是人工智能的简称),小X想写一个基于机器学习的国际象棋 AI,目标是战胜 IBM 的深蓝,小X的国际象棋水平也不差,曾获得过市青少年比赛的冠军,机器学习顾名思义就是让机器像人一样学习,小X首先训练机器学习棋子对棋盘的控制,具体做法是小X先在棋盘上放置若干个车和后,然后让机器判断有多少个格子没有被车和后控制到。
车和后的吃子规则如下:车:横、竖均可以走,步数不受限制,但不能斜着走。后:横、竖、斜都可以走,步数不受限制。无论是车还是后都不能越过棋子去吃子,用作训练的国际象棋棋盘可以放大缩小,并不限于 8×8 的棋盘,车和后所在的位置当然是被控制的,它们能走到的位置也都被控制。
输入
第一行包含一个正整数 n,表示棋盘的大小
接下来 n 行,每行 n 个整数,其中 0 表示棋盘上这个格子为空的,1 表示为车,2 表示为后
输出
一行一个整数,表示没有被控制到的格子数量
样例输入
复制样例数据
5 0 0 0 0 0 0 1 0 1 0 0 0 2 0 0 0 1 0 1 0 0 0 0 0 0
样例输出
4
提示
红色格子为样例中被控制到的格子,中间那个后能够斜着走到四个角落的格子(图中白色的格子),但因受到四个车的阻隔而不能控制到那四个格子!
数据范围
20%的数据,保证棋盘上只有车
50%的数据,n<=50
80%的数据,n<=200
100%的数据,n<=1000,车的数量<=n*n,后的数量<=n
先将che,hou放进容器中,这样就不需要在暴力枚举一遍了。che只需要扫一遍行和列,遇到有che或者hou就终止
对于hou,需要考虑行和列,对于一个知识点需要知道
主对角线横坐标-纵坐标的的值相同,次对角线横坐标+纵坐标的值相同。
注意的地方就是遇到扫行,列,斜线时遇到che和hou要终止。
/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>
typedef long long LL;
using namespace std;
int n, a[1005][1005], vis[1005][1005], ans;
struct node
{
int x, y;
};
vector<node> vechou, vecche;
void solvehou(int x, int y){
int t1 = x - y, t2 = x + y;
for (int i = x + 1; i <= n; i++){ //主对角线往下
if(i - t1 < 1 || i - t1 > n || vis[i][i - t1] == 2) break;
if(!vis[i][i - t1]) ans++;
vis[i][i - t1] = 1;
}
for (int i = x - 1; i >= 1; i--){//主对角线往上
if(i - t1 < 1 || i - t1 > n || vis[i][i - t1] == 2) break;
if(!vis[i][i - t1]) ans++;
vis[i][i - t1] = 1;
}
for (int i = x + 1; i <= n; i++){//次对角线往下
if(t2 - i < 1 || t2 - i > n || vis[i][t2 - i] == 2) break;
if(!vis[i][t2 - i]) ans++;
vis[i][t2 - i] = 1;
}
for (int i = x - 1; i >= 1; i--){//次对角线往上
if(t2 - i < 1 || t2 - i > n || vis[i][t2 - i] == 2) break;
if(!vis[i][t2 - i]) ans++;
vis[i][t2 - i] = 1;
}
}
void solveche(int x, int y){
for (int i = y + 1; i <= n; i++){
if(vis[x][i] == 2) break;
else if(!vis[x][i]) vis[x][i] = 1, ans++;
}
for (int i = y - 1; i >= 1; i--){
if(vis[x][i] == 2) break;
else if(!vis[x][i]) vis[x][i] = 1, ans++;
}
for (int i = x + 1; i <= n; i++){
if(vis[i][y] == 2) break;
else if(!vis[i][y]) vis[i][y] = 1, ans++;
}
for (int i = x - 1; i >= 1; i--){
if(vis[i][y] == 2) break;
else if(!vis[i][y]) vis[i][y] = 1, ans++;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
scanf("%d", &a[i][j]);
if(a[i][j] == 2) vechou.push_back(node{i, j}), vis[i][j] = 2;
else if(a[i][j] == 1) vecche.push_back(node{i, j}), vis[i][j] = 2;
}
}
int hou = vechou.size(), che = vecche.size();
for (int i = 0; i < hou; i++){
int x = vechou[i].x, y = vechou[i].y;
solvehou(x, y);
solveche(x, y);
}
for (int i = 0; i < che; i++){
int x = vecche[i].x, y = vecche[i].y;
solveche(x, y);
}
printf("%d\n", n *n - ans - hou - che);
return 0;
}
/**/