NOIP模拟9.28
2017-09-28 20:51
260 查看
2013提高D2
A.积木大赛(模拟+递归+st表)AC
B.花匠(贪心)AC
C.华容道(bfs+spfa)40.搜索手残写挂,本来有70分的。
C正解是:因为图是不变的,有很多询问,所以我们考虑预处理。记空白格为白块,目标块为黑块,目标位置为目标位置。
考虑到我们关心的状态只是白块和黑块的位置,而只有白块在黑块周围时,黑块的位置才会改变,因此我们用状态x,y,k表示黑块在(x,y),白块在黑块的k方向上。(k=0,1,2,3,分别对应下,上,右,左)我们考虑转移,以黑块的位置改变作为一次转移。例如黑块位置为(x,y),我们想要把它移动到位置(x+1,y),则我们要先把白块移到(x+1,y),假设这需要w步,然后再用一步交换黑块和白块的位置,使得白块到达(x+1,y),而黑块到达(x,y)。一共需要走(w+1)步,我们发现这样转移的话,黑块一定总是在白块周围,因此我们可以这样建图:
1.(x,y,k)->(xx,yy,re(k)),边权为1,表示黑白块交换位置(re[k]就是k的反方向)
2.(x,y,k)->(x,y,kk),边权用bfs算一下即可,表示黑块从白块的k方向,移动到白块的kk方向所需的步数。
然后对于每一个询问,我们先把白块移动到黑块周围,最多四种可能,分别用bfs算出步数,放入队列,然后跑spfa即可。
满分bfs+spfa
A.积木大赛(模拟+递归+st表)AC
B.花匠(贪心)AC
C.华容道(bfs+spfa)40.搜索手残写挂,本来有70分的。
C正解是:因为图是不变的,有很多询问,所以我们考虑预处理。记空白格为白块,目标块为黑块,目标位置为目标位置。
考虑到我们关心的状态只是白块和黑块的位置,而只有白块在黑块周围时,黑块的位置才会改变,因此我们用状态x,y,k表示黑块在(x,y),白块在黑块的k方向上。(k=0,1,2,3,分别对应下,上,右,左)我们考虑转移,以黑块的位置改变作为一次转移。例如黑块位置为(x,y),我们想要把它移动到位置(x+1,y),则我们要先把白块移到(x+1,y),假设这需要w步,然后再用一步交换黑块和白块的位置,使得白块到达(x+1,y),而黑块到达(x,y)。一共需要走(w+1)步,我们发现这样转移的话,黑块一定总是在白块周围,因此我们可以这样建图:
1.(x,y,k)->(xx,yy,re(k)),边权为1,表示黑白块交换位置(re[k]就是k的反方向)
2.(x,y,k)->(x,y,kk),边权用bfs算一下即可,表示黑块从白块的k方向,移动到白块的kk方向所需的步数。
然后对于每一个询问,我们先把白块移动到黑块周围,最多四种可能,分别用bfs算出步数,放入队列,然后跑spfa即可。
A
#include <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 100010 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,a ,st [20],Log ; ll ans=0; inline int rmq(int x,int y){ int t=Log[y-x+1]; return min(st[x][t],st[y-(1<<t)+1][t]); } void solve(int st,int ed,int val){ if(st>ed) return; int x=rmq(st,ed),l=st;ans+=x-val; while(l<=ed&&a[l]==x) l++; for(int i=l+1;i<=ed;++i){ if(a[i]==x){ solve(l,i-1,x);l=i+1;while(l<=ed&&a[l]==x) l++;i=l; } }solve(l,ed,x); } int main(){ // freopen("a.in","r",stdin); n=read();Log[0]=-1; for(int i=1;i<=n;++i) Log[i]=Log[i>>1]+1; for(int i=1;i<=n;++i) a[i]=read(),st[i][0]=a[i]; for(int i=1;i<=Log ;++i) for(int j=1;j<=n;++j) if(j+(1<<i-1)<=n) st[j][i]=min(st[j][i-1],st[j+(1<<i-1)][i-1]); int l=1;while(l<=n&&a[l]==0) l++; for(int i=l+1;i<=n;++i){ if(a[i]==0){ solve(l,i-1,0);l=i+1;while(l<=n&&a[l]==0) l++;i=l; } }solve(l,n,0); printf("%d\n",ans); return 0; }
B
#include <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 100010 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,a ,num=0,ans=0; int main(){ // freopen("a.in","r",stdin); n=read();a[++num]=read(); for(int i=2;i<=n;++i){ int x=read();if(x!=a[num]) a[++num]=x; } if(num==1){puts("1");return 0;} for(int i=2;i<=num-1;++i){ if(a[i]<a[i-1]&&a[i]<a[i+1]) ans++; if(a[i]>a[i-1]&&a[i]>a[i+1]) ans++; } printf("%d\n",ans+2); return 0; }
C
70分bfs#include <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 32 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,m,qu,ex,ey,sx,sy,tx,ty,ans=0,dx[]={1,-1,0,0},dy[]={0,0,1,-1}; bool mp ,f ; struct node{ int ex,ey,sx,sy,k; node(int _ex,int _ey,int _sx,int _sy,int _k){ ex=_ex;ey=_ey;sx=_sx;sy=_sy;k=_k; } }; int bfs(){ queue<node>q; node tmp(ex,ey,sx,sy,0);q.push(tmp);f[ex][ey][sx][sy]=1; while(!q.empty()){ node x=q.front();q.pop(); if(x.ex==tx&&x.ey==ty){ for(int i=0;i<4;++i) if(x.sx+dx[i]==tx&&x.sy+dy[i]==ty) return x.k+1; } for(int i=0;i<4;++i){ int xx=x.ex+dx[i],yy=x.ey+dy[i]; if(xx<1||xx>n||yy<1||yy>m||!mp[xx][yy]) continue; if(xx==x.sx&&yy==x.sy){ if(!f[xx][yy][x.ex][x.ey]){ f[xx][yy][x.ex][x.ey]=1; node y(xx,yy,x.ex,x.ey,x.k+1);q.push(y); } } else if(!f[xx][yy][x.sx][x.sy]){ f[xx][yy][x.sx][x.sy]=1; node y(xx,yy,x.sx,x.sy,x.k+1);q.push(y); } } } return -1; } int main(){ // freopen("puzzle13.in","r",stdin); // freopen("a.out","w",stdout); n=read();m=read();qu=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) mp[i][j]=read(); while(qu--){ ex=read(),ey=read(),sx=read(),sy=read();tx=read(),ty=read(); if(sx==tx&&sy==ty){puts("0");continue;} memset(f,0,sizeof(f)); printf("%d\n",bfs()); } return 0; }
满分bfs+spfa
#include <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define pa pair<pair<int,int>,int> #define N 32 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,m,qu,dx[]={1,-1,0,0},dy[]={0,0,1,-1},h [4],num=0,d [4]; bool mp ,f ,inq [4]; struct edge{ pa to;int next,val; }data[N*N*10]; inline void add(int x,int y,int k,pa xx,int val){ data[++num].to=xx;data[num].next=h[x][y][k];h[x][y][k]=num;data[num].val=val; } inline int re(int k){ if(k==0||k==2) return k+1;else return k-1; } int bfs(int sx,int sy,int tx,int ty){ memset(f,0,sizeof(f)); queue<pa>q;q.push(make_pair(make_pair(sx,sy),0));f[sx][sy]=1; while(!q.empty()){ int x=q.front().first.first,y=q.front().first.second; int step=q.front().second;q.pop(); if(x==tx&&y==ty) return step; for(int i=0;i<4;++i){ int xx=x+dx[i],yy=y+dy[i]; if(xx<1||xx>n||yy<1||yy>m||!mp[xx][yy]) continue; if(!f[xx][yy]) q.push(make_pair(make_pair(xx,yy),step+1)),f[xx][yy]=1; } }return inf; } void spfa(int ex,int ey,int sx,int sy,int tx,int ty){ if(sx==tx&&sy==ty){puts("0");return;} queue<pa>q;memset(d,0x3f,sizeof(d));mp[sx][sy]=0; for(int i=0;i<4;++i){ int x=sx+dx[i],y=sy+dy[i]; if(x<1||x>n||y<1||y>m||!mp[x][y]) continue; d[sx][sy][i]=bfs(ex,ey,x,y); if(d[sx][sy][i]==inf) continue; q.push(make_pair(make_pair(sx,sy),i));inq[sx][sy][i]=1; }mp[sx][sy]=1; while(!q.empty()){ int x=q.front().first.first,y=q.front().first.second; int k=q.front().second;q.pop();inq[x][y][k]=0; for(int i=h[x][y][k];i;i=data[i].next){ pa yy=data[i].to; if(d[yy.first.first][yy.first.second][yy.second]>d[x][y][k]+data[i].val){ d[yy.first.first][yy.first.second][yy.second]=d[x][y][k]+data[i].val; if(!inq[yy.first.first][yy.first.second][yy.second]){ inq[yy.first.first][yy.first.second][yy.second]=1;q.push(yy); } } } } int ans=inf; for(int i=0;i<4;++i) ans=min(ans,d[tx][ty][i]); if(ans==inf) puts("-1"); else printf("%d\n",ans); } int main(){ // freopen("puzzle7.in","r",stdin); n=read();m=read();qu=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) mp[i][j]=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ if(!mp[i][j]) continue;mp[i][j]=0; for(int k=0;k<4;++k){ int x=i+dx[k],y=j+dy[k]; if(x<1||x>n||y<1||y>m||!mp[x][y]) continue; add(i,j,k,make_pair(make_pair(x,y),re(k)),1); for(int kk=0;kk<4;++kk){ if(kk<=k) continue; int xx=i+dx[kk],yy=j+dy[kk]; if(xx<1||xx>n||yy<1||yy>m||!mp[xx][yy]) continue; int val=bfs(x,y,xx,yy); add(i,j,k,make_pair(make_pair(i,j),kk),val); add(i,j,kk,make_pair(make_pair(i,j),k),val); } }mp[i][j]=1; } while(qu--){ int ex=read(),ey=read(),sx=read(),sy=read(),tx=read(),ty=read(); spfa(ex,ey,sx,sy,tx,ty); } return 0; }
相关文章推荐
- NOIP2016提高A组模拟9.28总结
- 【JZOJ4803】【NOIP2016提高A组模拟9.28】求导
- 【JZOJ4804】【NOIP2016提高A组模拟9.28】成绩调研
- 【JZOJ4805】【NOIP2016提高A组模拟9.28】跟踪
- 【NOIP2016提高A组模拟9.28】求导
- 【NOIP2012模拟10.26】雕塑
- [noip模拟2017.7.3]
- 3453. 【NOIP2013中秋节模拟】连通块(connect)
- 【NOIP2013模拟10.23】君と彼女の恋
- 【JZOJ4920】【NOIP2017提高组模拟12.10】降雷皇
- 【NOIP2013模拟11.4A组】游乐场
- 【NOIP2016提高A组模拟9.15】Osu
- 3929. 【NOIP2014模拟11.6】创世纪
- 【NOIP模拟考一】组合数学 day1 third 子集
- NOIP模拟(20171024)T3 数学
- 【NOIP2016提高A组模拟9.15】Osu
- [NOIP模拟]beautiful
- JZOJ100041. 【NOIP2017提高A组模拟7.12】列车调度
- NOIP模拟10.26
- Math【NOIP2016提高A组模拟9.15】