您的位置:首页 > 其它

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即可。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: