hdu 3688 蛮巧的模拟
2012-02-01 16:43
381 查看
没想出来,参考了网上的做法
枚举两个灯之间的最大距离,易知答案至少是这个距离的一半。
枚举每个灯,去掉不符合条件的灯,即level值小于当前ans的,这个时间是O(1)的,只是更改一下上下左右灯(如果有)的指向的灯
复杂度为输入的复杂度O(n*m)
View Code
枚举两个灯之间的最大距离,易知答案至少是这个距离的一半。
枚举每个灯,去掉不符合条件的灯,即level值小于当前ans的,这个时间是O(1)的,只是更改一下上下左右灯(如果有)的指向的灯
复杂度为输入的复杂度O(n*m)
View Code
#include<cstdio> #include<cstring> #include<ctype.h> #include<algorithm> using namespace std; const int inf = 100000000; const int maxn = 11111; struct Light{ int x,y,level; int next[4]; Light(){} Light(int _x,int _y,int _level){ x=_x; y=_y; level=_level; for(int i=0;i<4;i++) next[i]=-1; } bool operator < (const Light &cmp) const{ return level<cmp.level; } void update(); }; int n,m,ans; int a[110][maxn]; Light light[110*maxn]; void Light::update(){ int left=next[0]; int right=next[2]; if(left!=-1) light[left].next[2]=right; if(right!=-1) light[right].next[0]=left; if(left==-1 && right == -1) ans=inf; else if(left==-1) ans=max(ans,light[right].y); else if(right==-1) ans=max(ans,m-light[left].y+1); else ans=max(ans,(light[right].y-light[left].y+2)/2); int up=next[1]; int down=next[3]; if(up!=-1) light[up].next[3]=down; if(right!=-1) light[down].next[1]=up; if(up==-1&&down==-1) ans=inf; else if(up==-1) ans=max(ans,light[down].x); else if(down==-1) ans=max(ans,n-light[up].x+1); else ans=max(ans,(light[down].x-light[up].x+2)/2); } int main(){ int i,j; while(scanf("%d%d",&n,&m),(n||m)){ int tot=0; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ scanf("%d",&a[i][j]); if(a[i][j]) light[++tot]=Light(i,j,a[i][j]); } } sort(light+1,light+tot+1); for(i=1;i<=tot;i++) a[light[i].x][light[i].y]=i; ans=0; int pre; for(i=1;i<=n && ans!=inf ; i++){ pre=-1; for(j=1;j<=m;j++){ if(a[i][j]){ if(pre==-1) ans=max(ans,j); else { ans=max(ans,j-pre+2)/2; light[a[i][j]].next[0]=a[i][pre]; light[a[i][pre]].next[2]=a[i][j]; } pre=j; } } if(pre==-1) ans=inf; else ans=max(ans,m-pre+1); } for(i=1;i<=m&&ans!=inf;i++){ pre=-1; for(j=1;j<=n;j++){ if(a[j][i]){ if(pre==-1) ans=max(ans,j); else { ans=max(ans,(j-pre+2)/2); light[a[j][i]].next[1]=a[pre][i]; light[a[pre][i]].next[3]=a[j][i]; } pre=j; } } if(pre==-1) ans=inf; else ans=max(ans,n-pre+1); } int t=1; while(ans<inf && t<=tot && light[t].level < ans) light[t++].update(); if(ans==inf) puts("NO ANSWER!"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- hdu 3688 模拟
- HDU 1048 What Is Your Grade? (简单模拟)
- hdu 2300 Crashing Robots(模拟)
- hdu 4121 模拟
- [ACM] HDU 5083 Instruction (模拟)
- HDU 2577 How to Type DP也可以模拟
- hdu 4801 Pocket Cube 四面魔方,模拟+搜索
- hdu 5095 多项式模拟+有坑
- HDU 1861 游船出租(模拟)
- HDU-#5038 Grade(模拟+Hash)
- hdu 1296 Polynomial Problem(模拟)
- HDU 1035 Robot Motion(简单题,模拟)
- hdu 4879 ZCC loves march (模拟+STL)
- hdu 1075 What Are You Talking About ( trie + 模拟 )
- hdu 5920 贪心+模拟
- hdu 2206 IP的计算(模拟)
- HDU - 1172 猜数字 (暴力+模拟)
- HDU 5510---Bazinga(指针模拟)
- HDU 4121 Xiangqi(模拟+恶心)
- HDU 5968 异或密码 【模拟】 2016年中国大学生程序设计竞赛(合肥)