problem 2 agar(agar.cpp)
题目描述
Skyfall 最近迷上了一个叫做 agar 的游戏。在这个游戏中,地图由 N*M 的点阵构成,每个 cell
占有一个点。体积大的 cell 可以吃掉体积小的 cell,吃掉之后,较大的 cell 的大小会增加被
吃掉的 cell 的大小。
比如:你的大小为 3,吃掉了一个大小为 2 的 cell 之后你的大小变为 5。
现在,地图上有 T 个细胞,第 i 个细胞的大小为 Qi,位置为 Xi,Yi 。( 保 证 这 T 个 cell 坐标互不
相同且 Qi>0)
这些 cell 被 dc 的魔法定住了(也就是说这些 cell 不可以主动移动) skyfall 的大
小为 Q0,skyfall 的出生位置为(X0,Y0),skyfall 可以向上向下向左向右运动
Skyfall 当然不想自己被吃掉,同时他也想知道自己最多吃掉多少个 cell
1:可能存在 skyfall 一个 cell 都吃不到的情况
2:若 skyfall 主动跟一个等大的 cell 在一个坐标,那么 skyfall 与他共存且不可移动
输入描述
第一行 N M T 表示地图的大小与细胞的个数接下来 T 行 每行三
个整数 Qi Xi Yi 表示第 i 个 cell 的大小位置
最后一行为 Q0 X0 Y0 表示 skyfall 的初始大小与位置
输出描述
两个整数:第一个整数表示 skyfall 最多吃掉多少细胞,第二个整数 skyfall 吃掉这些细胞后的最
终大小
如果 skyfall 被吃了,输出”233”(不带引号)
样例输入
3 3 4
10 1 1
4 1 2
10 2 1
2 3 3
5 2 2
样例输出
4 31
数据范围及提示
对于 50%的数据,N<=10,M<=10,所有细胞的大小均在 100 以内随机得到。
对于 100%的数据,N,M <= 1000;T<=50000,所有数据的大小均在 long long 范围内(意思就是
你不需要打高精),每个细胞的坐标均满足:1<=x<=N,1<=y<=M。
AC Code:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; typedef long long ll; int dx[]={0,0,-1,1},dy[]={1,-1,0,0}; ll map[1100][1100]; bool vis[1100][1100]; ll n,m,t,Q; ll read() { char ch=‘ ‘;int w=1;ll a=0; while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) w=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) a=a*10+ch-‘0‘,ch=getchar(); return w*a; } struct node{ int x,y; }; queue<node>q; priority_queue<ll,vector<ll>,greater<ll> >h; ll ansc=0,ansz=0; void bfs() { while(q.size()) { node a=q.front();q.pop(); int x=a.x,y=a.y; for(int i=0;i<4;i++) { int xx=x+dx[i],yy=y+dy[i]; if(xx>0&&xx<=n&&yy>0&&yy<=m&&!vis[xx][yy]) { vis[xx][yy]=1; if(map[xx][yy]>=ansz) //!!若存在现在吃不了的细胞 可先将其加入一个小根堆 等到再遇到可以吃的细胞时再判断能否被吃掉 就不用再回去吃了 { h.push((ll){map[xx][yy]}); } else { if(map[xx][yy]) { ansc++,ansz+=map[xx][yy]; //!! 当时吃不了的细胞 现在可能会被吃掉 while(h.size()&&h.top()<ansz) { ansz+=h.top(); ansc++; h.pop(); } q.push((node){xx,yy}); } else { q.push((node){xx,yy}); } } } } } } int main() { n=read(),m=read(),t=read(); ll x,y; for(int i=1;i<=t;i++) { Q=read(),x=read(),y=read(); map[x][y]=Q; } Q=read(),x=read(),y=read(); if(map[x][y]>Q) //如果正好出生在比它大的细胞上 就会直接被吃掉 { printf("233");return 0; } else { ansz+=Q; //!!! 先加上自身的大小 因为会存在”出生在和它等大的细胞上“的情况 if(map[x][y]&&map[x][y]<Q) //如果出生在比它小的细胞上 答案累加 ansz+=map[x][y],ansc++; } q.push((node){x,y}); vis[x][y]=1; bfs(); printf("%lld %lld",ansc,ansz); return 0; } /* 3 3 4 10 1 1 4 1 2 10 2 1 2 3 3 5 2 2 4 31 */
原文地址:https://www.cnblogs.com/Loi-Brilliant/p/8783442.html