zoukankan      html  css  js  c++  java
  • 「JOISC 2016 Day 2」三明治

    「JOISC 2016 Day 2」三明治
    这题真正让我感受了记搜的强大。
    我真的没想过搜索可以过(400)的啊喂
    对,( ext{NOI})还可以过(1e5)

    解法

    一个并不显然的(n^4)的做法是枚举每一个点,然后上下左右记忆化搜索。考试的时候觉得难打,但是看完别人的代码之后发现还挺好打的。就是开一个变量看看当前需要释放哪里才可以释放自己就可以了。一个要注意的地方是,如果自己搜到了自己,那显然这种情况不成立,这块是吃不了的。
    然后就想(n^3)的做法了。因为一个点要释放出来要不就是左边空了,要不就是右边空了。所以可以直接分别从左到右边搜一次,从右边到左边搜一次,信息可以重复利用因为之前的方块不成立当前就不成立,取之前的方块要吃的三明治这块也少不了。然后大力(DFS)就没了。

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    #define R register
    #define LL long long
    const int inf = 0x3f3f3f3f;
    const int N = 400 + 10;
    
    inline int read() {
    	char a = getchar(); int x = 0,f = 1;
    	for(; a > '9' || a < '0'; a = getchar()) if(a == '-') f = -1;
    	for(; a >= '0' && a <= '9' ;a = getchar()) x = x * 10 + a - '0';
    	return x * f;
    }
    int n,m;
    char s[N][N];
    int vis[N][N], f[N][N];
    int tot;
    inline void dfs(int x, int y, int op) {
    	if(x < 1 || x > n || y < 1 || y > m || tot >= inf) return ;
    	if(vis[x][y] == -1) { tot = inf; return ;}
    	if(vis[x][y]) return ;
    	tot += 2; vis[x][y] = -1;
    	if(s[x][y] == 'N') {
    		if(!op) dfs(x + 1, y, op ^ (s[x + 1][y] == 'Z')), dfs(x, y - 1, op);
    		else dfs(x - 1, y, op ^ (s[x - 1][y] == 'Z')), dfs(x, y + 1, op);
    	}
    	else {
    		if(!op) dfs(x - 1, y, op ^ (s[x - 1][y] == 'N')), dfs(x, y - 1, op);
    		else dfs(x + 1, y, op ^ (s[x + 1][y] == 'N')), dfs(x, y + 1, op);
    	}
    	vis[x][y] = 1;
    }
    
    int main() {
    	//freopen("sandwich.in","r",stdin);
    //	freopen("sandwich.out","w",stdout);
    	n = read(), m = read();
    	for(R int i = 1; i <= n; i ++)	scanf("%s",s[i] + 1);
    	memset(f, inf, sizeof(f));
    	for(R int i = 1; i <= n; i ++) {
    		memset(vis, 0, sizeof(vis)); tot = 0;
    		for(R int j = 1; j <= m; j ++) {
    			dfs(i, j, 0); f[i][j] = min(f[i][j], tot);
    		}
    		memset(vis, 0, sizeof(vis)); tot = 0;
    		for(R int j = m; j >= 1; j --) {
    			dfs(i, j, 1); f[i][j] = min(f[i][j], tot);
    		}
    	}
    	for(R int i = 1; i <= n; i ++)
    		for(R int j = 1; j <= m; j ++) {
    			if(f[i][j] >= inf) f[i][j] = -1;
    			printf("%d%c",f[i][j], j == m ? '
    ' : ' ');
    		}
    	return 0;	
    }
    
  • 相关阅读:
    C# 全局热键
    Frida hook 初识
    xposed hook 复杂函数参数问题
    C# http post 中文乱码问题
    Fiddler 抓包https 问题
    C# HttpWebRequest 多线程超时问题
    Android Studio 无 Generate signed apk 菜单选项问题
    c#调用c++ dll const char* String类型转换问题。传值,与接收返回值问题
    C++中GB2312字符串和UTF-8之间的转换
    The underlying connection was closed: An unexpected error occurred on a send
  • 原文地址:https://www.cnblogs.com/clover4/p/12912894.html
Copyright © 2011-2022 走看看