您的位置:首页 > 其它

C - A Game of Balls CodeChef - GAMEBALL 思维模拟

2017-05-31 23:44 357 查看
题目链接

题意

你在一块 n × m 的网格上玩一种“球类游戏”。网格中有一个格子是空的,剩下的每个格子中

都有一颗球。你可以进行任意次下面两类操作:

选择一个与空格子相邻的格子,并将格子中的球移动到空格子中。两个格子如果有公共边,

则认为他们相邻。

选择横向或者纵向上连续的三个格子,要求最中间的格子中有球,剩下的两个格子中一个有

球一个没有。你可以让不在中间的格子中的球跳过中间的格子,落到空格子中,并摧毁中间

格子里的球。操作后中间的格子也变成了空格子。

你的目标是只在棋盘上留下一颗球。每组数据中,你最多进行 5000 次操作。输出任意合法的

操作序列即可。如果目标无法达成,则输出-1。

数据

输入的第一行包含一个整数 T,代表测试数据的组数。接下来是 T 组数据。

每组数据的第一行包含两个空格分隔整数 n 和 m,代表网格的长宽。

接下来 n 行,每行包含一个长度为 m 的字符串,代表初始的网格。如果字符为‘*’,则代表对

应的格子中有一颗球;如果为‘.’,则代表格子为空。

对于每组数据,首先输出一行,包含一个整数 X,代表操作步数。如果无法达成目标,则输

出-1。X 不应超过 5000。

如果目标可以达成,那么接下来输出 X 行,每行包含四个由空格分隔的整数 x1, y1, x2, y2。如

果你进行的是第一类操作,那么意味着你将球从 (x1, y1) 移动到了 (x2, y2);如果你进行的是第二

类操作,那么意味着你将求从不在中间的格子 (x1, y1) 移动到了另一个不在中间的格子 (x2, y2)。

1 <= T <= 100, 1 <= n, m <= 10。

输入

1

2 3

***

**.

输出

8

2 1 2 3

1 1 2 1

1 3 1 1

2 1 2 2

2 3 2 1

2 1 2 2

2 2 1 2

1 1 1 3

思路:

因为对于这个题,题目中没有要求要找到最少的操作步数,所以我们只要找到一种即可.

我们可以只考虑**. 的情况,我们先要做的就是变为*..,然后在将*移到中间.*.,在将其余的移过来变为**.以此类推.

这样我们在跳的时候只需要对固定的这三个格子进行了操作,很巧妙.

我们这里定义三个函数一个up,一个down,一个left,用来调整*.(即将所有的全部下移,在左移,在上移,在上移为**.

对这固定的几个格子进行操作即可)

#include<bits/stdc++.h>
using namespace std;
char s[20][20];
int ans[5555][10];
char ss[20][20];
int n,m,t;
int cnt=0;
void up(int pos)
{
for(int i=pos;i>3;i--)
{
ans[cnt][0]=i,ans[cnt][1]=1;
ans[cnt][2]=i-1,ans[cnt++][3]=1;
}
return ;
}
void left(int pos)
{
for(int i=pos;i>1;i--)
{
ans[cnt][0]=n,ans[cnt][1]=i;
ans[cnt][2]=n,ans[cnt++][3]=i-1;
}
return ;
}
void down(int i,int pos)
{
for(int j=i;j<n;j++)
{
ans[cnt][0]=j,ans[cnt][1]=pos;
ans[cnt][2]=j+1,ans[cnt++][3]=pos;
}
return ;
}
void jump()
{
ans[cnt][0]=3,ans[cnt][1]=1;
ans[cnt][2]=1,ans[cnt++][3]=1;
ans[cnt][0]=1,ans[cnt][1]=1;
ans[cnt][2]=2,ans[cnt++][3]=1;
return ;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
if(n*m==1)
{
printf("-1\n");
continue;
}
if(n*m==2)
{
printf("0\n");
continue;
}
if(max(n,m)<=2)
{
printf("-1\n");
continue;
}
int flag=0;
if(n<=2)
{
memcpy(ss,s,sizeof(ss));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
s[j][i]=ss[i][j];
swap(n,m);
flag=1;
}
cnt=0;
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(s[i][j]=='.')
{
for(int k=j-1;k>=1;k--)
{
ans[cnt][0]=i,ans[cnt][1]=k;
ans[cnt][2]=i,ans[cnt++][3]=k+1;
}
for(int k=i-1;k>=1;k--)
{
ans[cnt][0]=k,ans[cnt][1]=1;
ans[cnt][2]=k+1,ans[cnt++][3]=1;
}
break;
}
}
}
for(int i=3;i<=n;i++)
{
up(i);
jump();
}
for(int i=2;i<=m;i++)
{
for(int j=n;j>=1;j--)
{
down(j,i);
left(i);
up(n);
jump();
}
}
printf("%d\n",cnt);
for(int i=0;i<cnt;i++)
{
if(!flag)
printf("%d %d %d %d\n",ans[i][0],ans[i][1],ans[i][2],ans[i][3]);
else
printf("%d %d %d %d\n",ans[i][1],ans[i][0],ans[i][3],ans[i][2]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: