题意:
就是有n*n*n个木块,然后给你m条三维的直线
问这些直线能够消掉多少个木块
思路:
其实就是求m条直线有几个交点
然后就是一个双重循环解决
然后读入的时候需要判重
用三个1000*1000的数组来实现。
注意
3 3
Y=2,Z=2
X=2,Y=2
X=2,Z=2
答案应该是7而不是6,因为三条线交在同一点上。
6的原因是在判断第一条线的时候 和后面两个都有交点,但是交点是同一个 其实只有1个。
这里的判重方法就是,用这条线没有的那个坐标进行判重。
因为对于Y=2,Z=2 交点的话只有X坐标不确定,所以用X坐标来判重。
代码:
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
int map[22][22];
int move[8][2]= {{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
int n;
struct winpoint
{
int cnt,x,y;
winpoint()
{
cnt=x=y=0;
}
};
int dfs(int x,int y,int f,int key)
{
int xx=x,yy=y;
int sum=0;
while(1)
{
sum++;
xx+=move[f][0];
yy+=move[f][1];
if(xx<0||yy<0||xx>=15||yy>=15) break;
if(map[xx][yy]!=key) break;
}
return sum;
}
winpoint ok1(int key)
{
winpoint ans;
for(int i=0; i<15; i++)
{
for(int j=0; j<15; j++)
{
if(map[i][j]!=-1) continue;
int f=0;
for(int k=0; k<4; k++)
{
if(dfs(i,j,k,key)+dfs(i,j,k+4,key)-1>=5) f=1;
if(f) break;
}
if(f)
{
if(ans.cnt==0)
{
ans.x=i;
ans.y=j;
}
ans.cnt++;
}
}
}
return ans;
}
int main()
{
while(scanf("%d",&n),n)
{
memset(map,-1,sizeof(map));
int f=-1;
int bl,wh;
bl=wh=0;
while(n--)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
map[x][y]=z;
if(z) bl++;
else wh++;
}
/*for(int i=0;i<15;i++)
{
for(int j=0;j<15;j++)
{
if(map[i][j]==-1) printf(".");
else printf("%d",map[i][j]);
}
puts("");
}*/
if(bl<wh||bl>=wh+2) //不合法
{
puts("Invalid.");
continue;
}
int key;
if(bl==wh) key=1;
else key=0;
winpoint ans;
ans=ok1(key);
if(ans.cnt>=1) //一步直接赢
{
printf("%s",key?"Place black ":"Place white ");
printf("at (%d,%d) to win in 1 move.\n",ans.x,ans.y);
continue;
}
ans=ok1(key^1);
if(ans.cnt>=2) //两个必胜点 直接输
{
puts("Lose in 2 moves.");
continue;
}
if(ans.cnt==1) //填对方必胜点 看能否赢
{
map[ans.x][ans.y]=key;
winpoint tep=ok1(key);
if(tep.cnt>=2) //对方堵不住 直接赢
{
printf("%s",key?"Place black ":"Place white ");
printf("at (%d,%d) to win in 3 moves.\n",ans.x,ans.y);
continue;
}
else //不能则不分胜负
{
puts("Cannot win in 3 moves.");
continue;
}
}
for(int i=0; i<15; i++)
{
for(int j=0; j<15; j++)
{
if(map[i][j]!=-1) continue;
map[i][j]=key;
winpoint tep=ok1(key);
if(tep.cnt>=2)
{
printf("%s",key?"Place black ":"Place white ");
printf("at (%d,%d) to win in 3 moves.\n",i,j);
f=1;
}
if(f==1) break;
map[i][j]=-1;
}
if(f==1) break;
}
if(f==-1) puts("Cannot win in 3 moves.");
}
return 0;
}