2019 年百度之星·程序设计大赛 - 初赛一 C. Mindis 离散化+dijkstra
题意:中文题面
思路:
先将所有题目给出的点离散化一下,得到一张n*m的网格,n和m最大都是400,所以我们只需要枚举每个加强的区域,将属于这个区域的边处理一下(所有横着的和竖着的边,暴力处理即可),然后相邻的点建边,建图,跑最短路即可。
mp[x][y][k]表示网格上横坐标x纵坐标y,方向为k(0,1,2,3表示上右下左)这条离散化后长度为1的边被矩形覆盖的次数(初始值为1),时间就是离散化前的长度除以次数.然后建边跑dijkstra。
比赛最后几分钟交了一发T了,发现离散化数组没排序就直接unique了,改完bug,bestcode就炸了。赛后补题,wa了两次,看着代码看了二十分钟,最后发现原来是oj没把题目搬完,交啥都是错的。。。搬完后就一发a了。。太伤心了。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,b,a) for(int i=b;i>=a;i--) #define clr(a,b) memset(a,b,sizeof(a)) #define pb push_back #define pii pair<int,int > using namespace std; typedef long long ll; ll rd() { ll 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; } const int maxn=5000+10; const int inf=0x3f3f3f3f; struct rc{ ll x1,x2,y1,y2; }a[300]; double mp[500][500][4]; vector<ll >vx,vy; ll xa,ya,xb,yb,n,m,num; struct edge{ int to; double w; friend bool operator<(const edge &a,const edge &b){ return a.w>b.w; } }; priority_queue<edge >q; vector<edge >ve[400000]; int getid(int x,int y){ return (y-1)*n+x; } bool check(int x,int y){ if(x<1||x>n||y<1||y>m)return false; return true; } double dis[400000]; void dij(){ int px1=lower_bound(vx.begin(),vx.end(),xa)-vx.begin()+1; int px2=lower_bound(vx.begin(),vx.end(),xb)-vx.begin()+1; int py1=lower_bound(vy.begin(),vy.end(),ya)-vy.begin()+1; int py2=lower_bound(vy.begin(),vy.end(),yb)-vy.begin()+1; int id1=getid(px1,py1),id2=getid(px2,py2); // printf("id1:%d id2:%d n:%d m:%d px1:%d py1:%d px2:%d py2:%d\n",id1,id2,n,m,px1,py1,px2,py2); dis[id1]=0; q.push({id1,0}); while(!q.empty()){ edge st=q.top(); q.pop(); int u=st.to; double w=st.w; // printf("u:%d w:%.4f\n",u,w); int si=ve[u].size(); rep(i,0,si-1){ int v=ve[u][i].to; if(dis[v]>dis[u]+ve[u][i].w){ dis[v]=dis[u]+ve[u][i].w; q.push({v,dis[v]}); } } } printf("%.5f\n",dis[id2]); } int main(){ int T; cin>>T; while(T--){ cin>>num; vx.clear(),vy.clear(); rep(i,1,num){ a[i].x1=rd(); a[i].y1=rd(); a[i].x2=rd(); a[i].y2=rd(); vx.pb(a[i].x1),vx.pb(a[i].x2); vy.pb(a[i].y1),vy.pb(a[i].y2); } cin>>xa>>ya>>xb>>yb; vx.pb(xa),vx.pb(xb); vy.pb(ya),vy.pb(yb); sort(vx.begin(),vx.end()); sort(vy.begin(),vy.end()); vx.erase(unique(vx.begin(),vx.end()),vx.end()); vy.erase(unique(vy.begin(),vy.end()),vy.end()); n=vx.size(),m=vy.size(); rep(i,1,n){ rep(j,1,m){ rep(k,0,3) mp[i][j][k]=1; ve[getid(i,j)].clear(); dis[getid(i,j)]=300000000000000; } } rep(i,1,num){ int px1=lower_bound(vx.begin(),vx.end(),a[i].x1)-vx.begin()+1; int px2=lower_bound(vx.begin(),vx.end(),a[i].x2)-vx.begin()+1; int py1=lower_bound(vy.begin(),vy.end(),a[i].y1)-vy.begin()+1; int py2=lower_bound(vy.begin(),vy.end(),a[i].y2)-vy.begin()+1; rep(x,px1+1,px2-1){ rep(y,py1+1,py2-1){ mp[x][y][0]++; mp[x][y][1]++; mp[x][y][2]++; mp[x][y][3]++; } } rep(x,px1+1,px2-1){ int y=py1; mp[x][y][0]++; mp[x][y][1]++; mp[x][y][3]++; y=py2; mp[x][y][2]++; mp[x][y][1]++; mp[x][y][3]++; } rep(y,py1+1,py2-1){ int x=px1; mp[x][y][0]++; mp[x][y][1]++; mp[x][y][2]++; x=px2; mp[x][y][0]++; mp[x][y][3]++; mp[x][y][2]++; } mp[px1][py1][0]++; mp[px1][py1][1]++; mp[px1][py2][2]++; mp[px1][py2][1]++; mp[px2][py1][0]++; mp[px2][py1][3]++; mp[px2][py2][3]++; mp[px2][py2][2]++; } rep(i,1,n){ rep(j,1,m){ int id=getid(i,j); if(check(i-1,j))ve[id].pb({getid(i-1,j),(vx[i-1]-vx[i-2])/mp[i][j][3]}); if(check(i+1,j))ve[id].pb({getid(i+1,j),(vx[i]-vx[i-1])/mp[i][j][1]}); if(check(i,j-1))ve[id].pb({getid(i,j-1),(vy[j-1]-vy[j-2])/mp[i][j][2]}); if(check(i,j+1))ve[id].pb({getid(i,j+1),(vy[j]-vy[j-1])/mp[i][j][0]}); } } dij(); } }
——愿为泰山而不骄
qq850874665~~
分类:
最短路
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!