ACM-ICPC World Finals 2022 L Where Am I? 题解
我们要干的事情其实是对于输入矩阵中的每个位置,求出从它开始至少走几步形成的序列能跟所有位置走同样步数形成的序列不同。注意到每个位置最多走步就能达到目标了,所以这时就有了一个的暴搜(把trie树搜出来),如果写得好是可以卡过去的!
但是还有更优的做法。注意到题目中说,输入的矩阵中最多只有100个X。所以可以对矩阵中的每个位置求出一个长度最多为100的序列,表示从这个位置开始走,形成的序列中的哪些位置是X。这一步可以做到(X的数量与n同阶,所以也用n表示了)。这时就可以用这些长为100的序列跑上面的暴搜,每次将一些位置分开的时候可以用map存。这一步的复杂度也是。
总复杂度。
点击查看代码
#include <bits/stdc++.h> #define rep(i,n) for(int i=0;i<n;++i) #define repn(i,n) for(int i=1;i<=n;++i) #define LL long long #define pii pair <int,int> #define fi first #define se second #define mpr make_pair #define pb push_back void fileio() { #ifdef LGS freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif } void termin() { #ifdef LGS std::cout<<"\n\nPROGRAM TERMINATED"; #endif exit(0); } using namespace std; int n,m,mxstp=42000,mx=-1; vector <pii> mxs,stps; double sum=0; string s[110]; vector <int> times[110][110]; map <pii,int> mp; void dfs(vector <pii> v,int ti,int pos) { if(v.size()==1) { sum+=ti; if(mx<ti){mx=ti;mxs={v[0]};} else if(mx==ti) mxs.pb(v[0]); return; } map <int,vector <pii> > mpp; rep(i,v.size()) mpp[times[v[i].fi][v[i].se][pos]].pb(v[i]); if(mpp.size()==1) dfs(v,ti,pos+1); else { int lstti=-1; for(auto it=mpp.begin();it!=mpp.end();++it) { if(it==(--mpp.end())) dfs(it->se,lstti,pos+1); else { lstti=it->fi; dfs(it->se,lstti,pos+1); } } } } int main() { fileio(); cin>>m>>n; rep(i,n) cin>>s[i]; repn(i,114514) { if(i%2==1) { rep(j,i) if(stps.size()<mxstp) stps.pb(mpr(-1,0)); rep(j,i) if(stps.size()<mxstp) stps.pb(mpr(0,1)); } else { rep(j,i) if(stps.size()<mxstp) stps.pb(mpr(1,0)); rep(j,i) if(stps.size()<mxstp) stps.pb(mpr(0,-1)); } if(stps.size()>=mxstp) break; } int curx=0,cury=0; rep(i,stps.size()) { mp[mpr(curx,cury)]=i; curx+=stps[i].fi;cury+=stps[i].se; } rep(i,n) rep(j,m) if(s[i][j]=='X') { rep(ii,n) rep(jj,m) times[ii][jj].pb(mp[mpr(i-ii,j-jj)]); } rep(i,n) rep(j,m) sort(times[i][j].begin(),times[i][j].end()),times[i][j].pb(114514); vector <pii> vv;rep(i,n) rep(j,m) vv.pb(mpr(i,j)); dfs(vv,0,0); printf("%.3lf\n%d\n",sum/n/m,mx); rep(i,mxs.size()) mxs[i]=mpr(mxs[i].se+1,n-mxs[i].fi); sort(mxs.begin(),mxs.end(),[](pii xx,pii yy){if(xx.se!=yy.se) return xx.se<yy.se;return xx.fi<yy.fi;}); rep(i,mxs.size()) printf("(%d,%d) ",mxs[i].fi,mxs[i].se); puts(""); termin(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话