您的位置:首页 > 其它

HDU-2259-Continuous Same Game (2)(BFS+DFS+模拟)

2014-09-02 10:48 369 查看
Problem Description

After repeated attempts, LL finds the greedy strategy is very awful in practice. Even there is no apparent evidence to proof it is better than a random one. So he has to drop this strategy and try to discover a better one. 

 

Input

There are 100 test cases. Each test case begins with two integers n,m ( 5<=n,m<=20 ), which is the size of the board. Then n lines follow, each contains m characters, indicating the color of the block. There are 5 colors, and each with equal probability.

 

Output

For each test case, first output a single line containing the number of steps S. Then S lines follow, each contains two integers indicating the position of an arbitrary block of the group you want to remove. 

For the i-th test case, let Ai is the total point of your scheme and Bi is the total point of the greedy strategy . Then I will calculate the average of (Ai/Bi), 1<=i<=100. You will get WA if your ouput is invalid or this average is less than 1.5.

 

Sample Input

5 5
35552
31154
33222
21134
12314

 

Sample Output

5
2 2
0 0
1 1
2 1
4 4

Hint
35552 35000 00000 00000 00000 00000
31154 31552 05552 00002 00002 00000
33222 33154 01154 01104 00004 00000
21134 21134 21134 21134 20034 20030
12314 12314 12314 12314 12314 12312

The total point is 6+12+12+12+6=48.

 

思路:总体是用BFS搞的,消除格子的时候就用DFS。对每一个状态都求一个评估值val,用优先队列来维护,每次使评估值最大的元素出队,并且更新答案。题目不要求最优解,处理25次左右就可以满足题意了。

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

struct S{
char mp[20][21];
int step,ans,x[50],y[50],val;
int num[20][20];

bool operator<(const S &p) const
{
return val<p.val;
}

}t,ans,tt;

int n,m,nxt[4][2]={{1,0},{0,1},{-1,0},{0,-1}},cnt;
char temp[20][21];
bool vis[20][20];

void dfs(int x,int y,char c)
{
int i,j;

for(i=0;i<4;i++)
{
x+=nxt[i][0];
y+=nxt[i][1];

if(x>=0 && x<n && y>=0 && y<m && !vis[x][y] && temp[x][y]==c)
{
vis[x][y]=1;

cnt++;

dfs(x,y,c);
}

x-=nxt[i][0];
y-=nxt[i][1];
}
}

void tran(int x,int y,char num,char (*d)[21])
{
for(int i=0;i<4;i++)
{
x+=nxt[i][0];
y+=nxt[i][1];

if(x>=0 && x<n && y>=0 && y<m && d[x][y]==num)
{
d[x][y]='0';

tran(x,y,num,d);
}

x-=nxt[i][0];
y-=nxt[i][1];
}
}

void move(char (*d)[21])
{
int i,j,k;

for(i=n-1;i>=0;i--)//向下移动
{
for(j=0;j<m;j++)
{
if(d[i][j]=='0')
{
for(k=i-1;k>=0;k--)
{
if(d[k][j]>'0')
{
d[i][j]=d[k][j];
d[k][j]='0';

break;
}
}
}
}
}

int t=m-1;
while(t--)//向左移动,注意连续两列都为空的情况
{
for(j=0;j<m-1;j++)
{
for(i=0;i<n;i++) if(d[i][j]>'0') break;

if(i==n)
{
for(i=0;i<n;i++)
{
d[i][j]=d[i][j+1];

d[i][j+1]='0';
}
}
}
}
}

void eval(S &node)//评估
{
int i,j;

for(i=0;i<n;i++) for(j=0;j<m;j++) vis[i][j]=0,temp[i][j]=node.mp[i][j];

node.val=node.ans;

for(i=0;i<n;i++) for(j=0;j<m;j++)
{
node.num[i][j]=0;

if(temp[i][j]>'0' && !vis[i][j])
{
vis[i][j]=1;

cnt=1;

dfs(i,j,temp[i][j]);

if(cnt>1)
{
node.num[i][j]=cnt;

node.val+=cnt*(cnt-1);
}
}
}
}

int main()
{
int i,j,p,q,tot;

while(~scanf("%d%d",&n,&m))
{
for(i=0;i<n;i++) scanf("%s",t.mp[i]);

t.step=0;
t.ans=0;
t.val=0;

ans.ans=0;

priority_queue<S>que;

eval(t);

que.push(t);

tot=0;

while(!que.empty())
{
t=que.top();

if(t.ans>ans.ans) ans=t;//更新答案

tot++;

if(tot>24) break;//循环25次就退出

que.pop();

for(i=0;i<n;i++) for(j=0;j<m;j++)
{
if(t.num[i][j])
{
tt=t;

tran(i,j,t.mp[i][j],t.mp);//清除格子

t.mp[i][j]='0';

move(t.mp);//移动格子

t.x[t.step]=i;
t.y[t.step]=j;
t.step++;
t.ans+=t.num[i][j]*(t.num[i][j]-1);

eval(t);//重新评估

que.push(t);

t=tt;
}
}
}

printf("%d\n",ans.step);

for(i=0;i<ans.step;i++) printf("%d %d\n",ans.x[i],ans.y[i]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: