TZOJ 7649: 瑞兹的法术涌动 模拟深搜广搜
描述
英雄联盟里的流浪法师瑞兹有一个技能叫做法术涌动,法术涌动会发射一团法球对命中的目标添加涌动效果并扩散至附近的敌人,该效果会持续4秒;如果试图施加涌动效果至一名已有涌动效果的敌人,那么该效果会进一步扩散(我们假设涌动是瞬间完成不计算时间),并且之前的涌动效果会刷新继续存在4秒。
现在给你一个n*n的小兵矩阵,初始时每个小兵都没有涌动效果,并给你q次施法机会,每次你会对第i行第j个小兵释放法术涌动,每次施法都会消耗1秒,请你计算q次施法后有多少个小兵的身上有法术涌动的效果
输入
输入第一行有两个整数n,q,代表小兵矩阵的大小和q次施法(1≤n≤100,1≤q≤50)
接下来q行,每行一个坐标x,y(1≤x,y≤100)
输出
输出q次施法后身上有涌动效果的小兵数量
样例输入
3 2
1 2
1 2
样例输出
6
提示
如果用1来代表有涌动效果,0代表没有涌动效果
那么3*3矩阵第一次在(1,2)施法后
0 1 0
0 0 0
0 0 0
第二次在(1,2)施法后
1 1 1
1 1 1
0 0 0
AC感想:瑞兹每次施法都会刷新该小兵的涌动时间,所以对于每一次施法,我们先找出这次施法会给哪些小兵施加上涌动效果,然后再扫一遍地图,对有涌动效果的小兵时长都+1,如果有小兵的涌动时长超过了4秒,那么这个涌动效果就会消失,对该小兵进行重置。
#include<bits/stdc++.h> using namespace std; struct node{ int x,y,t=0,f=0;//x,y是坐标,t是当前的涌动时长,f代表是否有涌动效果 }; node a[101][101]; int book[101][101]; int n,m,q,sx,sy,f; int nex[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},{1,1},{1,-1},{-1,-1}}; void dfs(int x,int y) { int tx,ty; for(int i=0;i<8;i++) { tx = nex[i][0]+x; ty = nex[i][1]+y; if(tx<1||ty<1||tx>n||ty>n)continue; if(a[tx][ty].f==0&&book[tx][ty]==0) {//如果该小兵没被标记过 a[tx][ty].f = 1; a[tx][ty].t = 0; book[tx][ty] = 1; } else if(a[tx][ty].f==1&&book[tx][ty]==0) {//如果该小兵有涌动效果但没有标记过,则让这个小兵重新附上涌动效果,并且以这个小兵为起点继续搜索是否可以扩散 a[tx][ty].t = 0; book[tx][ty] = 1; dfs(tx,ty); } } } int main() { cin>>n>>q; for(int k=1;k<=q;k++) { memset(book,0,sizeof(book));//因为每次施法都要搜一遍,所以要初始化标记数组 cin>>sx>>sy; if(a[sx][sy].f==0)//该小兵没有涌动效果,标记上 { a[sx][sy].f=1; } else {//整体搜一遍,看看能搜多少 book[sx][sy] = 1; a[sx][sy].t = 0; dfs(sx,sy); } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(a[i][j].f==1) { a[i][j].t++; if(a[i][j].t>4) { a[i][j].f=0; a[i][j].t=0; } } //cout<<a[i][j].f<<" "; } //cout<<endl; } } int ans=0; for(int i=1;i<=n;i++)//扫一遍地图看看还有多少小兵有涌动效果 { for(int j=1;j<=n;j++) { if(a[i][j].f==1)ans++; } } cout<<ans<<endl; return 0; }