求助十分

P3956 [NOIP2017 普及组] 棋盘

%%%
by Luo_gu_fyh @ 2022-07-27 14:21:43


1. 采用优先队列,按每个格子最小代价排序; ```cpp template<class T = int> struct myNode { T x,y,color,cost; myNode(T newx,T newy,T newcolor,T newcost){x = newx; y = newy; color = newcolor; cost = newcost;} myNode(const myNode& obj){ x = obj.x; y = obj.y; color = obj.color; cost = obj.cost;} bool operator<( const myNode<T>& b) const { return cost > b.cost; } }; //template<class T> //bool operator<(const myNode<T>& a,const myNode<T>& b) //此类操作符重载一定不能突变任何东西,并且两个操作数必须都是const //{ // return a.cost > b.cost; //} priority_queue<myNode<int> > myque;//距离优先队列 ``` 2. BFS(int x,int y, int color ,int cost) ```cpp void mybfs(int x,int y,int color,int cost) //无色格子在bfs是被更改为其父节点的颜色入队,原地图上的颜色不变 { int currentx,currenty,currentcolor,currentcost; if(mycolor[x][y] != -1)//每次bfs(x,y)时,根据原始地图mycolor(x,y)判断是否为有色格子 for(int i = 0; i < 4; ++i) { currentx = x + mydx[i]; currenty = y + mydy[i]; currentcolor = mycolor[currentx][currenty]; if(!myvis[currentx][currenty]) { if((mycolor[currentx][currenty] == mycolor[x][y])) //将与x,y相临且颜色相同的格子,设置与(x,y)相同的cost currentcost = cost; else if(mycolor[currentx][currenty] != -1) //将与x,y相临且颜色相异的格子,cost设置(x,y)的cost+1 currentcost = cost + 1; else//将与x,y相临且无色的格子,cost设置(x,y)的cost+2,颜色与(x,y)相同 { currentcolor = color; currentcost = cost + 2; } myvis[currentx][currenty] = 1;//设计计算标志,并入队 myque.push(myNode<int>(currentx,currenty,currentcolor,currentcost)); } } else //据原始地图mycolor(x,y)判断(x,y)为无色格子 { for(int i = 0; i < 4; ++i) //检查(x,y)周围是否有未计算的有色格子,将其入队cost { currentx = x + mydx[i]; currenty = y + mydy[i]; if(!myvis[currentx][currenty] && mycolor[currentx][currenty] != -1) { if(mycolor[currentx][currenty] == color) //(x,y) 的临时颜色为color,相临的有色点与(x,y)临时同色 currentcost = cost; else //与(x,y)相临的有色点,与(x,y)颜色不同 currentcost = cost + 1; myvis[currentx][currenty] = 1; myque.push(myNode<int>(currentx,currenty,mycolor[currentx][currenty],currentcost)); } } } } ``` 3. 主程序 ```cpp int main() { int m,n,ans; memset(mycolor,-1,sizeof(mycolor));//初始每个格子为无色-1; memset(myvis,0,sizeof(myvis)); //0表示没有被访问 cin >> m >> n; for(int i = 1; i <= n; ++i) //读入有颜色的各个格子,并设置好颜色值 { int x,y,color; cin >> x >> y >> color; mycolor[x][y] = color; } for(int i = 0; i <= m; ++i)//0列与0行的格子在棋盘之外,默认被计算过不可达 myvis[0][i] = myvis[i][0] = 1; ans = -1;//默认目标不能到达 myvis[1][1] = 1; myque.push(myNode<int>(1,1,mycolor[1][1],0)); while(!myque.empty()) { myNode<int> tmp = myque.top() ; myque.pop(); if(tmp.x == m && tmp.y == m) //到达目标 { ans = tmp.cost; break; } else mybfs(tmp.x,tmp.y,tmp.color,tmp.cost); } cout << ans << endl; return 0; } ```
by lglwff @ 2022-07-28 00:10:23


明白了谢谢巨佬 @[lglwff](/user/30110)
by 流光剑客 @ 2022-07-31 18:52:55


|