• POJ3669 Meteor Shower 题解


    CSDN同步

    原题链接

    题目不难。

    肯定考虑宽搜。

    首先搞定一个事实:一个格子不会重复走。如果可以重复走,则必然有可以替代它的不重复走的不劣的方案。很明显:如果你走到一个格子又 可以不 走回来,那就有了替代方案;如果你走到一个格子又 不得不 走回来,那就不走这 (2) 步,也有了替代方案。因此,不重复走格子。这非常重要。

    幸亏这题不像某些搜索题一样(就特定时间砸在上面,以后还是可以走的),还要考虑原地停留,考虑重复走格子的复杂情况。

    然后就是模拟了。先预处理出每个格子最早的砸掉的时间,然后宽搜去走就行了。

    时间复杂度:(mathcal{O}(nm)). 其中 (n = max_{x_i} , m = max_{y_i}),满足 (n,m leq 300).

    一个注意点:答案有可能超过 (300),因为完全可以构造一种情况使得你必须跑到最外面去,因为岩石对周围的格子也有影响,注意开大数组。

    #include<cstdio>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    const int Max=1e9+7;
    
    inline int read(){char ch=getchar(); int f=1; while(!isdigit(ch)) {if(ch=='-') f=-f; ch=getchar();}
    	   int x=0;while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}
    
    struct node {
    	int x,y,tim;
    };
    
    int M,a[305][305];
    bool h[305][305];
    queue<node> q;
    
    inline node mp(int x,int y,int tim) {
    	node t; t.x=x; t.y=y; t.tim=tim;
    	return t;
    }
    
    int main() {
    	M=read();
    	for(int i=0;i<=303;i++) for(int j=0;j<=303;j++) a[i][j]=Max;
    	for(int i=1;i<=M;i++) {
    		int x=read(),y=read(),z=read();
    		a[x][y]=min(a[x][y],z);
    		if(x) a[x-1][y]=min(a[x-1][y],z);
    		if(y) a[x][y-1]=min(a[x][y-1],z);
    		a[x+1][y]=min(a[x+1][y],z); a[x][y+1]=min(a[x][y+1],z);
    	} if(a[0][0]==0) return puts("-1"),0;
    /*	for(int i=0;i<=7;i++) {
    		for(int j=0;j<=7;j++) {
    			if(a[i][j]==Max) cout<<"-1 ";
    			else cout<<setw(3)<<a[i][j];
    		}
    		puts("");
    	}*/
    	q.push(mp(0,0,0)); h[0][0]=1;
    	while(!q.empty()) {
    		int x=q.front().x,y=q.front().y,tim=q.front().tim; q.pop();
    //		printf("%d %d %d
    ",x,y,tim);
    		if(x && tim+1<a[x-1][y] && !h[x-1][y]) {
    			if(a[x-1][y]==Max) return printf("%d
    ",tim+1),0;
    			q.push(mp(x-1,y,tim+1)); h[x-1][y]=1;
    		}
    		if(y && tim+1<a[x][y-1] && !h[x][y-1]) {
    			if(a[x][y-1]==Max) return printf("%d
    ",tim+1),0;
    			q.push(mp(x,y-1,tim+1)); h[x][y-1]=1;
    		}
    		if(tim+1<a[x+1][y] && !h[x+1][y]) {
    			if(a[x+1][y]==Max) return printf("%d
    ",tim+1),0;
    			q.push(mp(x+1,y,tim+1)); h[x+1][y]=1;
    		}
    		if(tim+1<a[x][y+1] && !h[x][y+1]) {
    			if(a[x][y+1]==Max) return printf("%d
    ",tim+1),0;
    			q.push(mp(x,y+1,tim+1)); h[x][y+1]=1;
    		}
    	} puts("-1");
    	return 0;
    }
    
    
    简易的代码胜过复杂的说教。
  • 相关阅读:
    游戏活动分析
    移动端页面设计指南
    20条开发AIR Native Extension的建议
    Feathers UI 扩展实例 For Starling Framework
    优化 Flash 性能 Flash 开发中心
    简单的不雅词语过滤类
    简单TSql备份所有数据库
    列出Server上5张最大的表
    Asp.net MVC RTM1.0使用NUnit做测试项目
    使用SingleTagSectionHandler实现简单配置节
  • 原文地址:https://www.cnblogs.com/bifanwen/p/15021701.html
Copyright © 2020-2023  润新知