• P3956 棋盘 题解


    CSDN同步

    原题链接

    简要题意:

    (1,1) 走到 (n,n);每次走过相同颜色的格子不用魔法,走过不同颜色(但有颜色)的格子用 (1) 个魔法;走到一个有颜色的格子上可以暂时将它变成某种颜色然后走上去,用 (2) 个魔法;但是这种魔法是暂时的,只要你离开那个格子,那个格子就会变回没有颜色的样子,并且不能连续使用 (2) 次。求到终点的最小魔法。(不好意思,题目中实际说的是“金币”,但理解成魔法无妨。

    首先,( exttt{dfs})( exttt{bfs}) 都可以实现本题。

    由于 ( exttt{dfs}) 代码原理简单,清晰有条理,所以考虑 深度优先搜索。

    • 函数参数:当前坐标(两个数),使用金币个数,是否能用魔法。

    • 状态转移:利用坐标转移公式,按照题意模拟。

    • 剪枝优化:记忆化当前坐标答案。

    具体细节见代码。

    时间复杂度:(O(n^2)).(有较大常数,但可以接受)

    实际得分;(100pts).

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    
    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;}
    
    int f[1001][1001],ans;
    int n,m,a[1001][1001];
    bool h[1001][1001];
    
    const int dx[4]={0,0,1,-1};
    const int dy[4]={1,-1,0,0}; //坐标转移
    
    inline void dfs(int x,int y,int coin,bool magic) {
    //	printf("%d %d %d %d
    ",x,y,coin,magic);
    	if(f[x][y]<=coin || coin>=ans) return; //即当前答案已经变劣
    	f[x][y]=coin;
    	if(x==n && y==n) {
    		ans=min(ans,coin);
    		return;
    	} for(int i=0;i<4;i++) {
    		int nx=x+dx[i],ny=y+dy[i];
    		if(nx<1 || ny<1 || nx>n || ny>n) continue;
    		if(!h[nx][ny]) {
    			h[nx][ny]=1;
    			if(a[nx][ny]) { //有颜色
    				if(a[x][y]==a[nx][ny]) dfs(nx,ny,coin,1);
    				else dfs(nx,ny,coin+1,1); //看用不用魔法
    			} else if(magic) { //可以用
    				a[nx][ny]=a[x][y];
    				dfs(nx,ny,coin+2,0); //下步不能用
    				a[nx][ny]=0; 
    			} h[nx][ny]=0; //返回状态防止影响下一步答案
    		}
    	}
    }
    
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=INT_MAX;
    	while(m--) {
    		int x=read(),y=read(),z=read();
    		a[x][y]=z+1; // 0 表示无色,所以 +1
    	} ans=INT_MAX; h[1][1]=1; dfs(1,1,0,1);
    	printf("%d
    ",ans==INT_MAX?-1:ans);
    	return 0;
    }
    
    
    
    
  • 相关阅读:
    Seconds_Behind_Master的计算
    innnodb 线程在做什么?
    Mysql Join_buffer_size的使用原理
    C 实现位图排序
    C 内存池的实现
    C实现队列
    mysqld执行的函数栈
    Source Insight的基本用法
    MySQL高性能以及高安全测试
    【设计篇】状态与策略
  • 原文地址:https://www.cnblogs.com/bifanwen/p/12634264.html
Copyright © 2020-2023  润新知