标签:width 枚举 链接 jpg current div == algorithm 大屏幕
题目链接http://noi.openjudge.cn/ch0201/7213/
2018年俄罗斯世界杯(2018 FIFA World Cup)开踢啦!为了方便球迷观看比赛,莫斯科街道上很多路口都放置了的直播大屏幕,但是人群散去后总会在这些路口留下一堆垃圾。为此俄罗斯政府决定动用一种最新发明——“垃圾炸弹”。这种“炸弹”利用最先进的量子物理技术,爆炸后产生的冲击波可以完全清除波及范围内的所有垃圾,并且不会产生任何其他不良影响。炸弹爆炸后冲击波是以正方形方式扩散的,炸弹威力(扩散距离)以d给出,表示可以传播d条街道。
例如下图是一个d=1的“垃圾炸弹”爆炸后的波及范围。
假设莫斯科的布局为严格的1025*1025的网格状,由于财政问题市政府只买得起一枚“垃圾炸弹”,希望你帮他们找到合适的投放地点,使得一次清除的垃圾总量最多(假设垃圾数量可以用一个非负整数表示,并且除设置大屏幕的路口以外的地点没有垃圾)。
1 2 4 4 10 6 6 20
1 30
查看
做这道题目的时候太急躁,还没有清晰的思路就急于编程,后果往往是思维陷入定式,程序的bug多。可以总结出来的经验,程序一定要在语义上面通顺正确,不能模棱两可,更不能有歧义。所以编程的时候,要做到能把程序的语义读出来。
接着讲这道题目的思路。这道题用枚举可以解决。查了一些资料,提供两种枚举方案。
方案一
枚举所有点(i,j),对每一个点,假设在该点安放炸弹,然后扫描所有大屏幕的坐标,统计有多少个大屏幕的坐标在该炸弹的波及范围内。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<vector> #define DEBUG(x) cout<<#x<<" = "<<x<<endl using namespace std; const int MAXN=1030; const int INF=0x3f3f3f3f; struct Pos{ int x,y,v; Pos(){} Pos(int i,int j,int w){ x=i,y=j,v=w; } }; vector<Pos>pv; int main() { // freopen("in.txt","r",stdin); int d,n; scanf("%d%d",&d,&n); int t=n; while(t--){ int i,j,v; scanf("%d%d%d",&i,&j,&v); pv.push_back(Pos(i,j,v)); } int pn=0,maxamnt=-1,tamnt=0; for(int r=0;r<=1024 ;r++ ){ for(int c=0;c<=1024 ;c++ ){ tamnt=0; for(int k=0;k<pv.size() ;k++ ){ int ltr=r-d,ltc=c-d,rbr=r+d,rbc=c+d; int rr=pv[k].x,cc=pv[k].y; if(rr>=ltr&&rr<=rbr&&cc>=ltc&&cc<=rbc) tamnt+=pv[k].v; } if(tamnt>maxamnt){ pn=1; maxamnt=tamnt; } else if(tamnt==maxamnt){ pn++; } } } printf("%d %d\n",pn,maxamnt); }
方案二
枚举所有大屏幕的点,确定包含这个大屏幕的投弹位置范围,然后扫描所有大屏幕的坐标,统计有多少个大屏幕的坐标在该炸弹的波及范围内。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<string> #include<vector> #define DEBUG(x) cout<<#x<<" = "<<x<<endl using namespace std; const int MAXN=1030; const int INF=0x3f3f3f3f; int vis[MAXN][MAXN]; struct Pos{ int x,y,v; Pos(){} Pos(int i,int j,int w){ x=i,y=j,v=w; } }; vector<Pos>pv; int main() { freopen("in.txt","r",stdin); int d,n; scanf("%d%d",&d,&n); int t=n; int si=INF,sj=INF,ei=-1,ej=-1; while(t--){ int i,j,v; scanf("%d%d%d",&i,&j,&v); pv.push_back(Pos(i,j,v)); } int pn=0,maxamnt=-1,tamnt; for(int i=0; i<pv.size() ; i++ ) { int lti=pv[i].x-2*d, ltj=pv[i].y-2*d, rbi=pv[i].x+2*d, rbj=pv[i].y+2*d; lti=max(lti,0); ltj=max(ltj,0); rbi=min(rbi,1024); rbj=min(rbj,1024); for(int r=lti; r<=rbi ; r++ ) { for(int c=ltj; c<=rbj ; c++ ) { tamnt=0; for(int k=0;k<n ;k++ ){ int ltr=r-d,ltc=c-d,rbr=r+d,rbc=c+d; int rr=pv[k].x,cc=pv[k].y; if(rr>=ltr&&rr<=rbr&&cc>=ltc&&cc<=rbc) tamnt+=pv[k].v; } if(tamnt>maxamnt) { pn=1; maxamnt=tamnt; vis[r][c]=1; } else if(tamnt==maxamnt) { if(vis[r][c]==0)pn++; vis[r][c]=1; } } } } printf("%d %d\n",pn,maxamnt); }
注意不能缩小枚举范围,因为虽然可以做到不影响收集垃圾的最大值,但是会影响投弹点的数目
标签:width 枚举 链接 jpg current div == algorithm 大屏幕
原文地址:https://www.cnblogs.com/MalcolmMeng/p/9392565.html