首页 > 代码库 > 首师大附中科创教育平台 我的刷题记录 0284 最强大脑

首师大附中科创教育平台 我的刷题记录 0284 最强大脑

从现在开始,我的刷题记录都开始给大家一个一个刷!今天给大家献上“E”级题:最强大脑!!

 试题编号:0284  
最强大脑
难度级别:E; 运行时间限制:3000ms; 运行空间限制:256000KB; 代码长度限制:2000000B
试题描述
zhb国是一个传说中的国度,国家的居民叫做最强(chang)大脑(diao)。Zhb国是一个N×M的矩形方阵,每个格子代表一个街区。
然而zhb国是没有交通工具的。居民大脑(diao)们完全靠地面的弹射装置来移动。
每个街区都装有弹射装置。使用弹射装置是需要支付一定费用的。而且每个弹射装置都有自己的弹射能力。

我们设第i行第j列的弹射装置有Aij的费用和Bij的弹射能力。并规定有相邻边的格子间距离是1。那么,任何居民大脑(diao)都只需要在(i,j)支付Aij的费用就可以任意选择弹到距离不超过Bij的位置了。如下图

 

(从红色街区交费以后可以跳到周围的任意蓝色街区。)
现在的问题很简单。有三个居民,她们分别是zhb的maze,分别叫做X,Y,Z。现在她们决定聚在一起玩找zhb玩(….),于是想往其中一人的位置集合。但由于zhb太抠门了,不给报销路费,所以告诉你3个maze的坐标,求往哪里集合大家需要花的费用总和最低。
Zhb:如果你完美解决了这个问题,就授予你“最强大脑”称号。

 
输入
输入的第一行包含两个整数N和M,分别表示行数和列数。
接下来是2个N×M的自然数矩阵,为Aij和Bij
最后一行六个数,分别代表X,Y,Z所在地的行号和列号。 
输出
第一行输出一个字符X、Y或者Z。表示最优集合地点。
第二行输出一个整数,表示最小费用。
如果无法集合,只输出一行NO 
输入示例
4 4
0 0 0 0
1 2 2 0
0 2 2 1
0 0 0 0
5 5 5 5
5 5 5 5
5 5 5 5
5 5 5 5
2 1 3 4 2 2 
输出示例
Z
15 
其他说明
20%  N, M ≤ 10;   Bij ≤ 20
40%  N, M ≤ 100;   Bij ≤ 20
100%  1 ≤ N, M ≤ 150;  0 ≤ Bij ≤ 109;  0 ≤ Aij ≤ 1000 

好的,以上就是最强大脑的题目要求,现在献上代码!!!当当当!!!

 

技术分享
#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<queue>#include<cstring>#define INF 2147483647using namespace std;inline int read(){ int x=0,t=1,c; while(!isdigit(c=getchar()))if(c==-)t=-1; while(isdigit(c))x=x*10+c-0,c=getchar(); return x*t;}bool is_in(int left,int down,int right,int up,int x,int y,int r){ if(left>right||down<up)return false; int X,Y,distx,disty; if(x<left)X=0; else if(x>=left&&x<=right)X=1; else if(x>right)X=2; if(y<up)Y=0; else if(y>=up&&y<=down)Y=1; else if(y>down)Y=2; if(X==0) {  if(Y==0)  {   distx=left-x;   disty=up-y;   if(distx+disty<=r)return true;   else return false;  }  if(Y==1)  {   if(left-x<=r)return true;   else return false;  }  if(Y==2)  {   distx=left-x;   disty=y-down;   if(distx+disty<=r)return true;   else return false;  } } if(X==1) {  if(Y==0)  {   if(up-y<=r)return true;   else return false;  }  if(Y==1)  {   return true;  }  if(Y==2)  {   if(y-down<=r)return true;   else return false;  } } if(X==2) {  if(Y==0)  {   distx=x-right;   disty=up-y;   if(distx+disty<=r)return true;   else return false;  }  if(Y==1)  {   if(x-right<=r)return true;   else return false;  }  if(Y==2)  {   distx=x-right;   disty=y-down;   if(distx+disty<=r)return true;   else return false;  } }}bool is_all_in(int left,int down,int right,int up,int x,int y,int r){ if(left>right||down<up)return false; int distx,disty; distx=abs(left-x); disty=abs(down-y); if(distx+disty>r)return false; disty=abs(y-up); if(distx+disty>r)return false; distx=abs(x-right); disty=abs(down-y); if(distx+disty>r)return false; disty=abs(y-up); if(distx+disty>r)return false; return true;}int first[140000],target[10000000],next[10000000],value[10000000],countn=1;void AddEdge(int u,int v,int length){ target[countn]=v; value[countn]=length; next[countn]=first[u]; first[u]=countn++;}int from,posx,posy,r,v,A[160][160],B[160][160];void build(int o,int left,int down,int right,int up,bool cut){ if(left==right&&up==down)return; int lc=o<<1,rc=lc+1,m; AddEdge(o,lc,0); AddEdge(o,rc,0); if((cut||left==right)&&up!=down) {  m=up+down>>1;  build(lc,left,m,right,up,!cut);  build(rc,left,down,right,m+1,!cut); } else {  m=left+right>>1;  build(lc,left,down,m,up,!cut);  build(rc,m+1,down,right,up,!cut); }}void update(int o,int left,int down,int right,int up,bool cut){ if(is_all_in(left,down,right,up,posx,posy,r)) {  AddEdge(from,o,v);  return; } int lc=o<<1,rc=lc+1,m; if((cut||left==right)&&up!=down) {  m=up+down>>1;  if(is_in(left,m,right,up,posx,posy,r))update(lc,left,m,right,up,!cut);  if(is_in(left,down,right,m+1,posx,posy,r))update(rc,left,down,right,m+1,!cut); } else {  m=left+right>>1;  if(is_in(left,down,m,up,posx,posy,r))update(lc,left,down,m,up,!cut);  if(is_in(m+1,down,right,up,posx,posy,r))update(rc,m+1,down,right,up,!cut); }}int query(int o,int left,int down,int right,int up,bool cut){ if(left==right&&up==down)return o; int lc=o<<1,rc=lc+1,m; if((cut||left==right)&&up!=down) {  m=up+down>>1;  if(posy<=m)return query(lc,left,m,right,up,!cut);  else return query(rc,left,down,right,m+1,!cut); } else {  m=left+right>>1;  if(posx<=m)return query(lc,left,down,m,up,!cut);  else return query(rc,m+1,down,right,up,!cut); }}struct State{ int pos,cost; bool operator < (const State &b)const {  return cost>b.cost; }}take,put;priority_queue<State> PQ;int fastest[140000],N,M;int Dijkstra(int x0,int y0,int x1,int y1){ memset(fastest,127,sizeof(fastest)); while(!PQ.empty())PQ.pop(); int s,t; posx=x0; posy=y0; s=query(1,1,N,M,1,0); posx=x1; posy=y1; t=query(1,1,N,M,1,0); put.pos=s; put.cost=0; PQ.push(put); while(!PQ.empty()) {  take=PQ.top();  PQ.pop();  if(fastest[take.pos]<take.cost)continue;  if(take.pos==t)  {   return take.cost;  }  for(int i=first[take.pos];i;i=next[i])  {   if(fastest[target[i]]>take.cost+value[i])   {    fastest[target[i]]=take.cost+value[i];    put.pos=target[i];    put.cost=fastest[put.pos];    PQ.push(put);   }  } } return -1;}int main(){ N=read(),M=read(); build(1,1,N,M,1,0); for(int i=1;i<=N;i++) {  for(int j=1;j<=M;j++)  {   B[i][j]=read();  } } for(int i=1;i<=N;i++) {  for(int j=1;j<=M;j++)  {   A[i][j]=read();   if(B[i][j])   {    posx=j;    posy=i;    r=B[i][j];    v=A[i][j];    from=query(1,1,N,M,1,0);    update(1,1,N,M,1,0);   }  } } int y0=read(),x0=read(),y1=read(),x1=read(),y2=read(),x2=read(); int XtoY,YtoX,XtoZ,ZtoX,YtoZ,ZtoY,ans=INF; char place=N; XtoY=Dijkstra(x0,y0,x1,y1); YtoX=Dijkstra(x1,y1,x0,y0); XtoZ=Dijkstra(x0,y0,x2,y2); ZtoX=Dijkstra(x2,y2,x0,y0); YtoZ=Dijkstra(x1,y1,x2,y2); ZtoY=Dijkstra(x2,y2,x1,y1); if(~YtoX&&~ZtoX) {  if(YtoX+ZtoX<ans)  {   place=X;   ans=YtoX+ZtoX;  } } if(~ZtoY&&~XtoY) {  if(ZtoY+XtoY<ans)  {   place=Y;   ans=XtoY+ZtoY;  } } if(~XtoZ&&~YtoZ) {  if(XtoZ+YtoZ<ans)  {   place=Z;   ans=XtoZ+YtoZ;  } } if(place==N)puts("NO"); else printf("%c\n%d",place,ans);}
最强大脑!!!!!

 

首师大附中科创教育平台 我的刷题记录 0284 最强大脑