问题
http://hihocoder.com/contest/hiho31/problem/1
解法
首先要理解题意,共有三种规则,这三种规则要独立使用。每个规则都是应用在输入数据上求得结果。
第三种规则两两相交有24种情况。
#include <bits/stdc++.h>
using namespace std;
enum{maxn = 200+5, isB = 9, notB = 10};
int G[maxn][maxn];
int res[maxn][maxn];
int n, m;
int Delt[8][2] = {{-1, -1}, {0, -1}, {1, -1},
{-1, 0}, {1, 0},{-1, 1}, {0, 1}, {1, 1}};
int d2[12][2] = {{2, -2},{2, -1},{2, 0},
{1, -2},{1, -1},{1, 0},
{0, -2},{0, -1},
{-1, -2},{-1, -1},
{-2, -2},{-2, -1},
};
void caseA(int i, int j)
{
for (int c=0; c<8; c++)
{
int ii = i+Delt[c][0];
int jj = j +Delt[c][1];
if (G[ii][jj] ==-1)
{
res[ii][jj] = notB;
}
}
}
void caseB(int i, int j)
{
int nkNum = 0;
int bNum = 0;
for(int c=0; c<8; c++)
{
int ii = i+Delt[c][0];
int jj = j +Delt[c][1];
if (G[ii][jj] ==-1)
nkNum++;
}
if (nkNum == G[i][j])
{
for (int c =0; c <8; c++)
{
int ii = i+Delt[c][0];
int jj = j +Delt[c][1];
if (G[ii][jj] ==-1)
{
res[ii][jj] = isB;
}
}
}
}
int getUkNum(int i, int j, int k, int s)
{
int uknum =0;
for (int c =0; c<8; ++c)
{
int ii = i+Delt[c][0];
int jj = j+Delt[c][1];
if ((abs(ii-k) >1 || abs(jj-s)>1) && G[ii][jj]==-1)
uknum++;
}
return uknum;
}
void setUkToB(int i, int j, int k, int s)
{
for (int c =0; c<8; ++c)
{
int ii = i+Delt[c][0];
int jj = j+Delt[c][1];
if ((abs(ii-k) >1 || abs(jj-s)>1) && G[ii][jj]==-1)
{
res[ii][jj] = isB;
}
}
}
void test(int i, int j, int k, int s)
{
int ukNum1 = getUkNum(i, j, k, s);
int ukNum2 = getUkNum(k, s, i, j);
if (ukNum1 ==0 && ukNum2&& ukNum2 == G[k][s] - G[i][j])
{
setUkToB(k, s, i, j);
}else if (ukNum2 ==0 && ukNum1 && ukNum1 == G[i][j] - G[k][s])
{
setUkToB(i,j, k, s);
}
}
void caseC(int i, int j)
{
for (int c =0; c<12; ++c)
{
int ii = i+d2[c][0];
int jj = j +d2[c][1];
if (1<=ii&& ii<=n && 1<=jj&& jj<=m && 0<=G[ii][jj] && G[ii][jj]<=8)
{
test(i, j, ii, jj);
}
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
memset(res, 0, sizeof(res));
for (int i=0; i<=n+1; ++i)
G[i][0] = G[i][m+1] = notB;
for (int i=0; i<=m+1; ++i)
G[0][i] = G[n+1][i] = notB;
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
scanf("%d", &G[i][j]);
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
{
if (0<=G[i][j] && G[i][j]<=8)
caseC(i, j);
if (G[i][j]==0)
caseA(i,j);
if (1<=G[i][j])
caseB(i, j);
}
int isNum = 0, notNum =0;
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
if (res[i][j] == isB)
isNum++;
else if (res[i][j] == notB)
notNum++;
printf("%d %d\n", isNum, notNum);
}
return 0;
}