题目大意:

别人说是消消看,至于你玩没玩过。反正我是没玩过的。

就是选择一个钻石,可以消除与它相连的所有钻石。并获得 消除数量*消除数量  的分

思路:

直接暴搜,然后用一个cnt数组表示每一种钻石剩余的数量,进行剪枝。

被坑了两天。 开始用BFS 搜,用DFS进行标记。超内存。

后来改成了  DFS + DFS 发现有些细节不好处理。

最后换成了DFS搜  BFS标记消除。

#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std;
int dx[] = {0,0,1,-1,1,1,-1,-1};
int dy[] = {1,-1,0,0,1,-1,-1,1}; int n,m,k;
int map[9][9]; int save[9][9][70];
bool vis[9][9][70];
int cnt[7];
int ans; struct node
{
int posx,posy;
}Q[1000];
bool ok(int x,int y)
{
if(x>=1 && x<=n && y>=1 && y<=m)return true;
return false;
}
void mtos(int dep)//存地图
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
save[i][j][dep]=map[i][j];
}
void stom(int dep)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
map[i][j]=save[i][j][dep];
} void reset(int top)//重新摆放
{
for(int i=0;i<top;i++)//与后面的BFS 对应 消除。
map[Q[i].posx][Q[i].posy]=0; int tmp[9][9]; int ii,jj;
for(int j=1;j<=m;j++)
{
ii=n;
for(int i=n;i>=1;i--)
{
if(map[i][j]!=0)
{
jj=j;
tmp[ii--][jj]=map[i][j];
}
}
while(ii>=1)
{
tmp[ii][j]=0;
ii--;
}
} int move[9],ccnt=0;
memset(move,0,sizeof(move)); for(int j=1;j<=m;j++)
{
if(tmp[n][j]==0)
{
move[j]=0;
ccnt++;
continue;
}
move[j]=ccnt;
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
tmp[i][j-move[j]]=tmp[i][j];
if(move[j])tmp[i][j]=0;
}
} for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
map[i][j]=tmp[i][j];
}
inline int h()//估价函数 剪枝
{
int sum=0; for(int i=1;i<=k;i++)
if(cnt[i]>=3)sum+=(cnt[i]*cnt[i]); return sum;
} int mark(int x,int y,int val,int dep)//进行标记
{
int head=0,tail=0;
node w,e; Q[tail].posx=x;
Q[tail++].posy=y;
vis[x][y][dep]=true;
while(head<tail)
{
w=Q[head];
head++;
for(int i=0;i<8;i++)
{
e=w;
int xx=e.posx+dx[i];
int yy=e.posy+dy[i]; if(ok(xx,yy) && !vis[xx][yy][dep] && map[xx][yy]==val)
{
vis[xx][yy][dep]=true;
e.posx=xx;
e.posy=yy;
Q[tail++]=e;
}
}
}
return tail;
} void dfs(int tans,int dep)
{
ans=max(ans,tans);
if(h()+tans<=ans)return; for(int i=1;i<=n;i++)//这里不可少 没进入一次新的DFS 都要重置
for(int j=1;j<=m;j++)
vis[i][j][dep]=false; for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]!=0 && !vis[i][j][dep])
{
int tscore=mark(i,j,map[i][j],dep); if(tscore>=3)
{
mtos(dep);
int vv=map[i][j];//被这里坑了好久 RESET之后地图就会变了。无力吐槽自己
cnt[vv]-=tscore;
reset(tscore);
dfs(tans+tscore*tscore,dep+1);
cnt[vv]+=tscore;
stom(dep);
}
}
}
}
} int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
cnt[map[i][j]]++;
}
ans=0;
memset(vis,false,sizeof(vis)); dfs(0,1);
printf("%d\n",ans);
}
return 0;
} /*
8 8 6
1 1 1 2 2 2 3 3
4 4 1 1 4 4 4 4
5 5 5 6 6 6 6 1
2 2 2 2 4 4 4 3
1 4 5 6 3 3 2 1
4 4 4 5 5 5 5 6
5 5 5 5 5 3 3 3
5 5 2 2 2 1 3 1
*/

这里在给出DFS + DFS 的 AC代码。 效率没有上一个快,只是为了检验自己之前的错误。

#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std;
int dx[] = {0,0,1,-1,1,1,-1,-1};
int dy[] = {1,-1,0,0,1,-1,-1,1};
int n,m,k;
int map[9][9]; int save[9][9][70];
bool vis[9][9][70];
int cnt[7];
int tscore;
int ans; void debugcnt()
{
for(int i=1;i<=k;i++)
printf("%d ",cnt[i]); puts("");
system("pause");
// getchar();
}
bool ok(int x,int y)
{
if(x>=1 && x<=n && y>=1 && y<=m)return true;
return false;
}
void debug()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%d",map[i][j]);
}
puts("");
}
puts("");
//getchar();
}
void mtos(int dep)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
save[i][j][dep]=map[i][j];
}
}
void stom(int dep)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
map[i][j]=save[i][j][dep];
}
}
void reset()
{
int tmp[9][9]; int ii,jj;
for(int j=1;j<=m;j++)
{
ii=n;
for(int i=n;i>=1;i--)
{
if(map[i][j]!=0)
{
jj=j;
tmp[ii--][jj]=map[i][j];
}
}
while(ii>=1)
{
tmp[ii][j]=0;
ii--;
}
} int move[9],ccnt=0;
memset(move,0,sizeof(move)); for(int j=1;j<=m;j++)
{
if(tmp[n][j]==0)
{
move[j]=0;
ccnt++;
continue;
}
move[j]=ccnt;
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
tmp[i][j-move[j]]=tmp[i][j];
if(move[j])tmp[i][j]=0;
}
} for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
map[i][j]=tmp[i][j];
}
int h()
{
int sum=0;
for(int i=1;i<=k;i++)
if(cnt[i]>=3)sum+=cnt[i]*cnt[i];
return sum;
} void mark(int x,int y,int val,int dep)
{
for(int i=0;i<8;i++)
{
int xx=dx[i]+x;
int yy=dy[i]+y;
if(ok(xx,yy) && !vis[xx][yy][dep] && map[xx][yy]==val)
{
vis[xx][yy][dep]=true;
map[xx][yy]=0;
tscore++;
mark(xx,yy,val,dep);
}
}
} void dfs(int tans,int dep)
{
if(tans+h()<=ans){return;}
ans=max(ans,tans); for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
vis[i][j][dep]=false; for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]!=0 && !vis[i][j][dep])
{
mtos(dep);
int tt;
tscore=0;
int vv=map[i][j]; mark(i,j,map[i][j],dep);
tt=tscore;
if(tt<3){stom(dep);continue;}
cnt[vv]-=tt;
reset();
dfs(tans+tt*tt,dep+1);
cnt[vv]+=tt;
stom(dep);
}
}
}
} int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
cnt[map[i][j]]++;
}
ans=0;
dfs(0,1); printf("%d\n",ans);
}
return 0;
}

再上一份自己之前超内存的BFS 的代码。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring> using namespace std;
int dx[] = {0,0,-1,1,1,1,-1,-1};
int dy[] = {1,-1,0,0,1,-1,1,-1};
int n,m,k;
struct node
{
short map[9][9];
int score;
}; bool vis[9][9];
bool v[9][9];
bool ok(int x,int y)
{
if(x<=n && x>=1 && y>=1 && y<=m)return true;
return false;
}
int tscore; void dfs(int x,int y,node &t,int val)
{
for(int i=0;i<8;i++)
{
int xx=dx[i]+x;
int yy=dy[i]+y;
if( ok(xx,yy) && !vis[xx][yy] && t.map[xx][yy]==val)
{
vis[xx][yy]=true;
t.map[xx][yy]=0;
tscore++;
v[xx][yy]=true;
dfs(xx,yy,t,val);
}
}
}
int h(node t)
{
int tcnt[7]; for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(t.map[i][j]!=0)
{
tcnt[t.map[i][j]]++;
}
}
}
int sum=0;
for(int i=1;i<=k;i++)
if(tcnt[i]>=3)sum+=tcnt[i]*tcnt[i]; return sum;
}
node reset(node t)
{
node tmp=t;
int ii,jj;
for(int j=1;j<=m;j++)
{
ii=n;
for(int i=n;i>=1;i--)
{
if(t.map[i][j]!=0)
{
jj=j;
tmp.map[ii--][jj]=t.map[i][j];
}
}
while(ii>=1)
{
tmp.map[ii][j]=0;
ii--;
}
}
//debug(tmp); int move[9],ccnt=0;
memset(move,0,sizeof(move)); for(int j=1;j<=m;j++)
{
if(tmp.map[n][j]==0)
{
move[j]=0;
ccnt++;
continue;
}
move[j]=ccnt;
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
tmp.map[i][j-move[j]]=tmp.map[i][j];
if(move[j])tmp.map[i][j]=0;
}
}
return tmp;
}
int ans;
void bfs(node t)
{
queue<node>Q; node w,e;
Q.push(t); while(!Q.empty())
{
w=Q.front();
Q.pop(); if(w.score>ans)
{
ans=w.score;
}
memset(v,false,sizeof(v)); for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(v[i][j])continue;
if(w.map[i][j]!=0)
{
e=w;
tscore=0;
memset(vis,false,sizeof(vis));
dfs(i,j,e,e.map[i][j]); if(tscore>=3)
{
e=reset(e);
e.score+=(tscore*tscore);
if(e.score+h(e)<=ans)continue;
Q.push(e);
}
}
}
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
node t;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&t.map[i][j]);
} t.score=0;
ans=0;
bfs(t);
printf("%d\n",ans);
}
return 0;
}

hdu 4090 GemAnd Prince的更多相关文章

  1. hdu 4090

    GemAnd Prince Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. HDU 4685 Prince and Princess 二分图匹配+tarjan

    Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...

  3. HDU 4685 Prince and Princess(二分图+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

  4. Prince and Princess HDU - 4685(匹配 + 强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  5. HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  6. H - Prince and Princess - HDU 4685(二分匹配+强连通分量)

    题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚. 分析:先求出来他们的最大匹配,因为给的数据未必是完备 ...

  7. hdu 4685 Prince and Princess(匈牙利算法 连通分量)

    看了别人的题解.须要用到匈牙利算法的强连通算法 #include<cstdio> #include<algorithm> #include<vector> #pra ...

  8. HDU 4685 Prince and Princess(二分匹配+强联通分量)

    题意:婚配问题,但是题目并不要求输出最大匹配值,而是让我们输出,一个王子可以与哪些王妃婚配而不影响最大匹配值. 解决办法:先求一次最大匹配,如果有两个已经匹配的王妃,喜欢她们两个的有两个或者以上相同的 ...

  9. HDU 4685 Prince and Princess

    强连通分量,看大神的题解才会写的.... http://www.cnblogs.com/kuangbin/p/3261157.html 数据量有点大,第一次Submit 2995ms过的,时限3000 ...

随机推荐

  1. 用C语言打印出三角函数

    在网上看到一个实例,是用C 中的* 打印出三角函数cos #include<stdio.h> #include<math.h> int main() { double y; i ...

  2. 分享一个 CSDN 自动评论角本

    先修改帐户名和密码 import requests from BeautifulSoup import BeautifulSoup import time def commitfunc(source_ ...

  3. Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l

    <pre name="code" class="python">[Thu May 5 11:02:27 2016] [error] Corrupte ...

  4. Nutch 是一个开源Java 实现的搜索引擎

    Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting,他同时也是Lucene.Hado ...

  5. 基于visual Studio2013解决算法导论之030二叉查找树

     题目 二叉查找树 解决代码及点评 // 12二叉查找树.cpp : 定义控制台应用程序的入口点. // // 3 - 10二叉搜索树查找.cpp : 定义控制台应用程序的入口点. // #in ...

  6. CMake入门指南

    原文地址:http://www.cnblogs.com/sinojelly/archive/2010/05/22/1741337.html CMake是一个比make更高级的编译配置工具,它可以根据不 ...

  7. Linux环境下编译并执行ava helloworld程序

    原文:http://blog.lupaworld.com/home-space-uid-24466-do-blog-id-2578.html 已经学会怎样在Windows下怎样编辑,编译和运行Java ...

  8. 高级UIKit-07(AVAudioPlayer)

    [day09-1-AVAudioPlayer]:播放音乐案例 实现多媒体需要准备以下两点: 需要引入一个框架AVFoundation.framework 然后引入#import <AVFound ...

  9. mysql 表级锁

    表级锁:分为读锁和写锁: lock tables table_name read;//其他事务只能读,不能加写锁,要等待更新. SESSION 50 执行: mysql> update test ...

  10. HDU4544 湫湫系列故事――消灭兔子

    HDU 4544 Tags: 数据结构,贪心 Analysis: 将兔子的血量从大到小排序,将箭的杀伤力从大到小排序,对于每一个兔子血量, 将比他大的杀伤力大的剑压入优先队列,优先队列自己重写,让它每 ...