Codeforces Round #224 (Div. 2) D 暴力搜索加记忆化

题意读了半年,英语太渣,题意是摆两个棋子在棋盘上作为起点,但是起点不能在#上,然后按照图的指示开始走, < 左 > 右 ^上 v下,走的时候只能按照图的指示走,如果前方是 #的话,可以走进去,但是 走进去之后便不能再走了,走的途中两个棋子不能相碰,但是最终都走到同一个#里是没事的,并且若是能走 无限步的话 输出 -1, 例如  > < 这样左右左右的走就能无限走,然后问你 两个棋子走的最大步数的和

一开始被输出-1给困住了,因为除了 .> <这样以外  还可以刚好形成一个圈,这样不太好判,而且不太敢写dfs因为 图是 2000 * 2000的有点大,反向的DFS也没想到,没法子也只能记忆化搜索一下,设dis[i][j]代表 由 (i,j)作为 起点能走的最远步数,这样觉得时间上应该能过去,然后枚举每一个点作为起点 进行深搜,这里就能判断是否为-1的情况,因为图为 2000 * 2000的,所以最多让你走 4000000步数,两个棋子一前一后跟着走的话
那么最多不会超过8000000,所以可以设置一个最大值MAXN = 8000000,一旦 重新走了标记过的也就是路过的点 就返回这个值,就能判定是否为-1,

求出每个点作为起点的最大步数以后,开始寻找,若有两个点的最大步数相同,而且他们在走的过程中没有相碰,这样最大步数和 就是 ans + ans  ,若找不到的话 一前一后放置两个棋子肯定就是最优得了  也就是 ans + ans - 1,好了就是代码的 实现了,深搜写的有点搓,

const int MAXN = 8000000 + 55;

char aa[2000 + 55][2000 + 55];

int mp[2000 + 55][2000 + 55];
int xx[5] = {-1,1,0,0};
int yy[5] = {0,0,-1,1};
int dis[2000 + 55][2000 + 55];
bool vis[2000 + 55][2000 + 55];
int bb[2000 + 55][2000 + 55];

int n,m;

int ans;

void init() {
	memset(aa,0,sizeof(aa));
	memset(mp,0,sizeof(mp));
	memset(dis,-1,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(bb,-1,sizeof(bb));
}

bool input() {
	while(scanf("%d %d",&n,&m) == 2) {
		for(int i=0;i<n;i++) {
			scanf("%s",aa[i]);
			for(int j=0;j<m;j++) {
				if(aa[i][j] == '#')mp[i][j] = -1;
				if(aa[i][j] == '^')mp[i][j] = 0;
				if(aa[i][j] == 'v')mp[i][j] = 1;
				if(aa[i][j] == '<')mp[i][j] = 2;
				if(aa[i][j] == '>')mp[i][j] = 3;
			}
		}
		return false;
	}
	return true;
}

bool isok(int x,int y) {
	if(x <0 || x >=n || y < 0 || y >= m)return true;
	return false;
}

int dfs1(int x,int y) {
	if(isok(x,y))return 0;
	if(vis[x][y])return MAXN;
	if(dis[x][y] != -1) return dis[x][y];
	vis[x][y] = 1;
	if(mp[x][y] == -1) {
		vis[x][y] = 0;
		dis[x][y] = 0;
		return 0;
	}
	else {
		int tmp = dfs1(x + xx[mp[x][y]],y + yy[mp[x][y]]) + 1;
		vis[x][y] = 0;
		dis[x][y] = tmp;
		return tmp;
	}
}

int dfs2(int x,int y,int cnt) {
	if(bb[x][y] != -1) {
		if(bb[x][y] != cnt || mp[x][y] == -1)return 1;
		else return 0;
	}
	if(mp[x][y] == -1) {
		bb[x][y] = cnt;
		return 1;
	}
	else {
		bb[x][y] = cnt;
		return dfs2(x + xx[mp[x][y]],y + yy[mp[x][y]],cnt + 1);
	}
}

void cal() {
	ans = 0;
	int mark;
	for(int i=0;i<n;i++) {
		for(int j=0;j<m;j++) {
			if(mp[i][j] == -1)continue;
			if(dis[i][j] != -1)continue;
			int tmp = dfs1(i,j);
			if(tmp >= MAXN){ans = MAXN;return;}
			ans = max(ans,tmp);
		}
	}
	if(ans == 0)return ;
	mark = 0;
	for(int i=0;i<n;i++) {
		for(int j=0;j<m;j++) {
			if(dis[i][j] == ans) {
				if(dfs2(i,j,1))mark++;
				if(mark > 1){ans *= 2;return ;}
			}
		}
	}
	ans += (ans - 1);
}

void output() {
	if(ans >= MAXN)puts("-1");
	else cout<<ans<<endl;
}

int main () {
	while(true) {
		init();
		if(input())return 0;
		cal();
		output();
	}
}

Codeforces Round #224 (Div. 2) D 暴力搜索加记忆化,布布扣,bubuko.com

时间: 2024-10-14 09:05:05

Codeforces Round #224 (Div. 2) D 暴力搜索加记忆化的相关文章

Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以当作 ( 可 ) . 问这个字符串有多少个子串是正确的括号串. tags:好考思维,想不到.. 预处理出每个字符向左向右最多可以匹配到哪里,再 O(n*n) 枚举所有区间,看是否符合条件. // C #include<bits/stdc++.h> using namespace std; #pra

Codeforces Round #174 (Div. 2)---D. Cow Program(dp, 记忆化搜索)

Farmer John has just given the cows a program to play with! The program contains two integer variables, x and y, and performs the following operations on a sequence a1,?a2,?-,?an of positive integers: Initially, x?=?1 and y?=?0. If, after any step, x

Codeforces Round #224 (Div. 2) B 数学推理

挺有意思的一道题目,一开始发现了循环节,做了一下,发现许多小地方要补,比较繁琐,做了几个小时的无用功吧,但是循环节肯定可以只是我写搓了,后来又推了公式,发现可以的 首先当b<x的时候,c--,a--那么对于 a,c来说他们之间的差并没有减小,所以真正起到作用的是b>=x的时候,这个时候只有c--,但是答案要求的 是多少次,在b<x的时候 是要经过一定次数的  w-(x - b)来重新使得b>=x,所以第二部分对答案有影响,但是 设方程的话 就不需要多设一个未知数,因为 第一部分肯定

Codeforces Round #253 (Div. 2)B(暴力枚举)

就暴力枚举所有起点和终点就行了. 我做这题时想的太多了,最简单的暴力枚举起始点却没想到...应该先想最简单的方法,层层深入. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<

Codeforces Round #258 (Div. 2)C(暴力枚举)

就枚举四种情况,哪种能行就是yes了.很简单,关键是写法,我写的又丑又长...看了zhanyl的写法顿时心生敬佩.写的干净利落,简直美如画...这是功力的体现! 以下是zhanyl的写法,转载在此以供学习: #include <vector> #include <list> #include <queue> #include <map> #include <set> #include <deque> #include <stac

Codeforces Round #312 (Div. 2)——C暴力技巧——Amr and Chemistry

Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting experiment. Amr has n different types of chemicals. Each chemical i has an initial volume of ai liters. For this experiment, Amr has to mix all the chemicals

Codeforces Round #363 (Div. 2) B 暴力

Description You are given a description of a depot. It is a rectangular checkered field of n × m size. Each cell in a field can be empty (".") or it can be occupied by a wall ("*"). You have one bomb. If you lay the bomb at the cell (x

Codeforces Round #313 (Div. 2) Equivalent Strings(搜索)

题目大意:判断两个字符串是否等价. 等价的条件(任意一条满足即可):1.两个字符串完全相同 2.把每个字符串分成长度相同的两部分,若a1等价于b1并且a2等价于b2,或者a1等价于b2并且a2等价于b1 由于等价的条件说得很模糊,我卡了不久.等价条件里的第2条的意思是,如果ab两个字符串的两两子串都满足这两个条件,那么ab是等价的(有点绕,对吧),如果我们都已经解读清楚这句话了,显然接下来我们可以递归判断等价了. 首先,如果两个字符串长度不相等,那么肯定不等价:如果当前字符串的长度是奇数,那么我

Codeforces Round #422 (Div. 2) A. I&#39;m bored with life 暴力

A. I'm bored with life Holidays have finished. Thanks to the help of the hacker Leha, Noora managed to enter the university of her dreams which is located in a town Pavlopolis. It's well known that universities provide students with dormitory for the