这套好丧……跟别的画风好不一样(中国风?)。提答没做也没测,假装只有两题吧。140/200
T1.ROBOTS
题目大意:h*w的网格上有n个机器人编号1~n,网格上有空地、墙、顺/逆时针转向器,每次可以把一个机器人朝一个方向推,机器人碰到空地会继续前进,碰到转向器会转向,碰到墙会在前一格停止,同一时间只能有一个机器人在动,编号连续的机器人可以合体,例如2号和3号合成[2,3],[2,3]和[4,6]合成[2,6],问把所有机器人合成一个最少要推几下,无解输出-1。(n<=9,h,w<=500)
思路:先记忆化搜索预处理出每个格子朝四个方向推各会推到哪里(注意可能会无限循环),用f[i][j][k][l]表示[i,j]并成一个机器人位于(k,l)格至少要推几下(内存较紧,需要hash),考虑dijkstra,堆的log难以接受,我想了个方法:答案肯定不会太大,于是每种权值开一个队列,这样复杂度是每次转移O(1),由于还要区间合并,最后时间复杂度大概是O(n^3hw),空间同样。不过实际上这个n^3不是满的,所以理论上应该是很科学的,不过我写了vector,常数好像有点大,本来想手写个链表加上内存回收搞不好就过了,因为懒而且还要打T2暴力就放弃了,最后得分85/100(都是T)。
#include<cstdio> #include<cstdlib> #include<vector> #include<queue> using namespace std; #define MN 500 #define MQ 11250000 struct pos{int x,y;}t[MN+5][MN+5][4]; const int o[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; char g[MN+5][MN+5]; int d[MQ+5],p[9][9],pl[45],pr[45],pn,x,y,l,r; pos work(int x,int y,int f) { if(t[x][y][f].x)return t[x][y][f]; t[x][y][f]=(pos){-1,-1}; int r; if(g[x][y]=='.'||(g[x][y]>='1'&&g[x][y]<='9'))r=f; if(g[x][y]=='A')r=f?f-1:3; if(g[x][y]=='C')r=f<3?f+1:0; return t[x][y][f]=(g[x][y]&&g[x][y]!='x')? work(x+o[r][0],y+o[r][1],r):(pos){x-o[f][0],y-o[f][1]}; } inline int hash(int x,int y,int l,int r){return x<0?-1:((x-1)*500+y-1)*pn+p[l][r];} inline void dehash(int z){l=pl[z%pn];r=pr[z%pn];y=(z/=pn)%500+1;x=z/500+1;} struct MyPQ { vector<queue<int> > v;int x; void push(int x,int z) { if(x<0||(d[x]&&d[x]<=z))return;d[x]=z; while(v.size()<z)v.push_back(queue<int>()); v[z-1].push(x); } inline int top(){return v[x].front();} inline void next(){for(v[x].pop();v[x].empty()&&x<v.size();++x);if(x==v.size())puts("-1"),exit(0);} inline void pop(){for(next();x>=d[v[x].front()];next());} }q; int main() { int n,w,h,i,j,k,z,zz; scanf("%d%d%d",&n,&w,&h);--n; for(i=1;i<=h;++i)scanf("%s",g[i]+1); for(i=0;i<9;++i)for(j=i;j<9;++j)pl[pn]=i,pr[pn]=j,p[i][j]=pn++; for(i=1;i<=h;++i)for(j=1;j<=w;++j) { for(k=0;k<4;++k)work(i,j,k); if(g[i][j]>='1'&&g[i][j]<='9')q.push(hash(i,j,g[i][j]-'1',g[i][j]-'1'),1); } while(true) { dehash(z=q.top());q.pop(); if(l==0&&r==n)return printf("%d",d[z]-1),0; for(i=0;i<l;++i)if(d[zz=hash(x,y,i,l-1)])q.push(hash(x,y,i,r),d[z]+d[zz]-1); for(i=8;i>r;--i)if(d[zz=hash(x,y,r+1,i)])q.push(hash(x,y,l,i),d[z]+d[zz]-1); for(j=0;j<4;++j)q.push(hash(t[x][y][j].x,t[x][y][j].y,l,r),d[z]+1); } }