Problem B. Rain Google APAC 2017 University Test Round A
2017-02-05 21:30
405 查看
这一题最初算法错了,竟然过了小数据,然后大数据一直WA,debug了好几天T_T。
最开始的想法是把非边界的点按照高度排序。从高度最低的点开始BFS。如果当前点所在的平面(同样高度的,包含当前点的连通平面)可以积水,就把该平面的高度更改为积水高度(积水区域border的最低高度)。
然而我更改过高度就没去管那些点了=。=实际上,被更改高度的点可能还没有被BFS,可是那些点和其他点高度大小关系已经变了。所以按照之前的次序BFS就不是先考虑高度最低的点了。e.g., 五个相邻的点原先为5 3 2 1 5,更改后为5 3 2 4 5,如果BFS还是从倒数第二个的点开始,那么因为2<4,就会认为无法积水。积水过程是5 3 3 4 5 -> 5 4 4 4 5。实际上如果先从2 BFS,仍然可以积水。积水过程是5 3 3 4 5 ->
5 4 4 4 5 -> 5 5 5 5 5。
正解是维护一个优先队列,这样每次BFS一个点之后都会将所有点按照更改后的高度高度重新排序。另外从优先队列pop元素之后,如果是更改之前的值,直接ignore。
最开始的想法是把非边界的点按照高度排序。从高度最低的点开始BFS。如果当前点所在的平面(同样高度的,包含当前点的连通平面)可以积水,就把该平面的高度更改为积水高度(积水区域border的最低高度)。
然而我更改过高度就没去管那些点了=。=实际上,被更改高度的点可能还没有被BFS,可是那些点和其他点高度大小关系已经变了。所以按照之前的次序BFS就不是先考虑高度最低的点了。e.g., 五个相邻的点原先为5 3 2 1 5,更改后为5 3 2 4 5,如果BFS还是从倒数第二个的点开始,那么因为2<4,就会认为无法积水。积水过程是5 3 3 4 5 -> 5 4 4 4 5。实际上如果先从2 BFS,仍然可以积水。积水过程是5 3 3 4 5 ->
5 4 4 4 5 -> 5 5 5 5 5。
正解是维护一个优先队列,这样每次BFS一个点之后都会将所有点按照更改后的高度高度重新排序。另外从优先队列pop元素之后,如果是更改之前的值,直接ignore。
#include<iostream> #include<stdio.h> #include<cstdio> #include<stdlib.h> #include<vector> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<queue> #include<ctype.h> #include<map> #include<time.h> #include<set> #include<bitset> #include<sstream> using namespace std; //Google APAC2017 Round A Problem B. Rain const int maxn=60; int T; int R; int C; int dx[]={0,-1,0,1}; int dy[]={-1,0,1,0}; int mp[maxn][maxn]; bool vis[maxn][maxn]; int ans; class node { public: int x; int y; int height; public: node() { x=0; y=0; height=0; } node(int x0,int y0,int h) { x=x0; y=y0; height=h; } bool operator < (node b) const { if(height==b.height) { if(x==b.x) { return y>b.y; } return x>b.x; } return height>b.height; } bool operator > (node b) const { if(height==b.height) { if(x==b.x) { return y<b.y; } return x<b.x; } return height<b.height; } }; set<node>mark; priority_queue<node>prique; int BFS(pair<int,int>st) { int minborder=0x3f3f3f3f; int area=0; memset(vis,false,sizeof(vis)); vector<pair<int,int> >neigh; neigh.clear(); queue<pair<int,int> >que; while(!que.empty()) que.pop(); que.push(st); while(!que.empty()) { pair<int,int>now=que.front(); neigh.push_back(now); que.pop(); vis[now.first][now.second]=true; if(now.first==1||now.first==R||now.second==1||now.second==C)//at the border { return 0; } area++; for(int i=0;i<4;i++) { int nextx=now.first+dx[i]; int nexty=now.second+dy[i]; if(nextx<1||nextx>R||nexty<1||nexty>C) continue; if(vis[nextx][nexty]==true) continue; if(mp[nextx][nexty]>mp[st.first][st.second]) { // cout<<mp[nextx][nexty]<<endl; minborder=min(minborder,mp[nextx][nexty]); continue; } else if(mp[nextx][nexty]<mp[now.first][now.second]) { return 0; } else if(mp[nextx][nexty]==mp[now.first][now.second]) { que.push(make_pair(nextx,nexty)); vis[nextx][nexty]=true; } //if smaller? //calc sum(heigh gap) instead of using product once } } // cout<<"here "<<st.first<<" "<<st.second<<" "<<area<<" "<<minborder<<" "<<mp[st.first][st.second]<<endl; if(minborder==0x3f3f3f3f) return 0; int ret=0; for(int i=0;i<neigh.size();i++) { // cout<<neigh[i].first<<" "<<neigh[i].second<<" "<<mp[neigh[i].first][neigh[i].second]<<" "<<st.first<<" "<<st.second<<" "<<mp[st.first][st.second]<<endl; mark.insert(node(neigh[i].first,neigh[i].second,mp[neigh[i].first][neigh[i].second])); ret+=minborder-mp[neigh[i].first][neigh[i].second]; mp[neigh[i].first][neigh[i].second]=minborder; prique.push(node(neigh[i].first,neigh[i].second,mp[neigh[i].first][neigh[i].second]));//neigh's height must < minborder } // cout<<"ret: "<<ret<<endl; return ret;//update value of mp? } int tmpmp[maxn][maxn]; int main() { freopen("B-small-practice.in","r",stdin); freopen("B-small-practice.out","w",stdout); scanf("%d",&T); for(int ca=1;ca<=T;ca++) { scanf("%d %d",&R,&C); memset(mp,0,sizeof(mp)); memset(tmpmp,0,sizeof(tmpmp)); while(!prique.empty()) prique.pop(); mark.clear(); ans=0; for(int i=1;i<=R;i++) { for(int j=1;j<=C;j++) { scanf("%d",&mp[i][j]); tmpmp[i][j]=mp[i][j]; if(i==1||j==1||i==R||j==C) continue; prique.push(node(i,j,mp[i][j])); } } while(!prique.empty()) { node tmp=prique.top(); prique.pop(); // cout<<tmp.x<<" "<<tmp.y<<" "<<tmp.height<<" "<<mark.count(tmp)<<endl; // continue; if(mark.count(tmp)==0) { ans+=BFS(make_pair(tmp.x,tmp.y)); } } printf("Case #%d: %d\n",ca,ans); } return 0; }
相关文章推荐
- Problem D. Stretch Rope Google APAC 2017 University Test Round D
- Problem D. Soldiers Google APAC 2017 University Test Round C
- Problem B. Sherlock and Watson Gym Secrets Google APAC 2017 University Test Round B
- Problem C. Watson and Intervals Google APAC 2017 University Test Round B
- Google APAC 2017 University Test Round B
- 【在线笔试题解题报告系列】Google APAC 2017 University Test Round A
- Problem A. Diwali lightings Google APAC 2017 University Test Round E
- Round A APAC Test 2017 Problem B.Rain
- Problem A. Vote Google APAC 2017 University Test Round D
- Problem A. Monster Path Google APAC 2017 University Test Round C
- 【在线笔试题解题报告系列】Google APAC 2017 University Test Round E
- Problem B. Safe Squares Google APAC 2017 University Test Round C
- Problem C. Codejamon Cipher Google APAC 2017 University Test Round D
- Problem B. Beautiful Numbers Google APAC 2017 University Test Round E
- Problem A. Lazy Spelling Bee Google APAC 2017 University Test Practice Round
- Problem B. gBalloon Google APAC 2016 University Test Round D
- 【在线笔试题解题报告系列】Google APAC 2017 University Test Round B
- Problem C. Evaluation Google APAC 2017 University Test Round C
- Problem B. Robot Rock Band Google APAC 2017 University Test Practice Round
- Problem A. Sherlock and Parentheses Google APAC 2017 University Test Round B