[JZOJ5046]机器人游戏
来源:互联网 发布:马踏棋盘 栈 贪婪算法 编辑:程序博客网 时间:2024/04/30 20:33
题目描述
小A和小B在一个
小A先将
游戏胜负规则如下:
●如果小机器人最终到达最后一列,且在游戏过程中经过了恰好一个黑色棋格(包括小机器人开始的棋格),那么小A获得胜利;如果小机器人经过了零个或大于一个黑色格子,那么小B获得胜利。
●如果机器人永远无法停下来,那么小A胜利。
题目保证每个棋格上的方向标记不会让小机器人走到棋盘外。
棋盘示意图如下:
现在小A想知道,他是否能找到一种涂黑格子的方案,使得不论小B如何放置游戏开始时的小机器人,他都能取得游戏的胜利。
题目分析
排除掉不会走到的格子以及会死循环的格子,所有格子都构成了一个森林。
现在的问题是要涂黑
这个问题存在树形依赖关系,可以使用很套路的DFS序dp:
令
注意因为那些不在森林上的点也可以涂黑,最后我们把它们的贡献考虑进去就好了。
记录方案的话,因为这题卡空间,所以我们记录涂黑点数直接用一个bool记录是否新涂黑了点就好了。
时间复杂度
代码实现
#include <iostream>#include <cstdio>#include <cctype>using namespace std;const int N=1000050;const int MAXK=55;int vis[N],fa[N],DFN[N],last[N],tov[N],nxt[N],size[N],p[N];int black[MAXK][2];bool dk[N][MAXK];bool f[N][MAXK];int g[N][MAXK];char MAP[N];int row,col,K,tot,idx,REM,bs;bool win;int getid(int x,int y){return x*col+y;}void getxy(int id,int &x,int &y){x=id/col,y=id%col;}void insert(int x,int y){tov[++tot]=y,nxt[tot]=last[x],last[x]=tot;}bool simulation(int x,int y,int cnt){ int id=getid(x,y); if (vis[id]==cnt) return 0; if (vis[id]) return 1; vis[id]=cnt; if (MAP[id]=='L') --y; if (MAP[id]=='R') ++y; if (MAP[id]=='U') --x; if (MAP[id]=='D') ++x; if (y+1==col) return 1; int id_=getid(x,y); return fa[id]=id_,simulation(x,y,cnt);}void dfs(int x){ p[DFN[x]=++idx]=x,size[x]=1; for (int i=last[x],y;i;i=nxt[i]) if ((y=tov[i])!=fa[x]) dfs(y),size[x]+=size[y];}void dp(){ win=0,f[1][0]=1; for (int x=1;x<=idx;++x) for (int k=0;k<=K;++k) if (f[x][k]) { if ((p[x]%col)&&!f[x+1][k]) f[x+1][k]=1,g[x+1][k]=x,dk[x+1][k]=0; if (k<K&&!f[x+size[p[x]]][k+1]) f[x+size[p[x]]][k+1]=1,g[x+size[p[x]]][k+1]=x,dk[x+size[p[x]]][k+1]=1; } for (int k=0;k<=K;++k) if (f[idx+1][k]&&K-REM<=k) { win=1; for (int id=g[idx+1][k],k_=k-dk[idx+1][k],k__=k;id!=0;k__=k_,k_-=dk[id][k_],id=g[id][k__]) if (k_!=k__) ++bs,getxy(p[id],black[bs][0],black[bs][1]),++black[bs][0],++black[bs][1]; REM=K-k; for (int x=0;x<row*col&&bs<K;++x) if (!DFN[x]&&(x%col!=col-1)) ++bs,getxy(x,black[bs][0],black[bs][1]),++black[bs][0],++black[bs][1]; break; }}int main(){ freopen("robots.in","r",stdin),freopen("robots.out","w",stdout); scanf("%d%d%d",&row,&col,&K); for (int i=0;i<row;++i) for (int j=0;j<col;++j) { char ch=getchar(); while (!isalpha(ch)) ch=getchar(); MAP[getid(i,j)]=ch; } win=0; if (col>1&&row*(col-1)>=K) { for (int x=0;x<row*col;++x) fa[x]=-1; for (int i=0;i<row;++i) simulation(i,0,i+1); REM=idx=0; for (int x=0;x<row*col;++x) if (fa[x]!=-1) insert(fa[x],x); for (int x=0;x<row*col;++x) if (vis[x]&&fa[x]==-1) dfs(x); REM=row*(col-1)-idx,dp(); }; if (!win) printf("-1\n"); else for (int i=1;i<=K;++i) printf("%d %d\n",black[i][0],black[i][1]); fclose(stdin),fclose(stdout); return 0;}
0 0
- [JZOJ5046]机器人游戏
- 【JZOJ5046】【NOI2017模拟4.5】机器人游戏
- 游戏机器人
- 机器人游戏
- 游戏机器人
- 游戏机器人(1)
- 游戏机器人(2)
- 游戏机器人(3)
- 游戏挂机机器人框架
- 【NOI2017】机器人游戏
- 【编程游戏】划拳机器人比赛
- android数独游戏机器人
- 【NOI2017模拟4.5】机器人游戏
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人----开发游戏机器人所需要的基本功 zz
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 谷歌开源谷歌地球企业版源码
- Excel导出报错 You can define up to 4000 styles in a .xls workbook
- preparestatement
- Android网络技术之WebView
- 获取操作系统是32还是64位
- [JZOJ5046]机器人游戏
- Niblack和局部均值算法的二值化比较
- div中class和id有什么区别?
- 每天一个Linux命令(23):Linux目录结构
- vc tcp端口是否被占用
- 强制断电引起的vmware无法启动
- 多个线程之间共享数据
- JDBC连接(Statement和PrepareStatement)
- Flex 布局