华农09年华山论剑:跳格子 scau 8636

7 篇文章 0 订阅
2 篇文章 0 订阅
题目
8636 跳格子
该题有题解

时间限制:2457MS  内存限制:1000K
提交次数:139 通过次数:46

题型: 编程题   语言: G++;GCC
Description
    地上有一个n*m 的数字格子,每个格子有一个坐标(i,j)(其中1<=i<=n , 1<=j<=m),规定左上角为(0,0),
右下角为(n,m),你要从最左端的一列的任意位置开始跳到最右边格子外。
下面两条你跳的时候的约束规则:
一、因为你的力气有限,每次只能跳一定的距离。给定一个k 为你的弹跳力,则从(i1,j1)起跳,你能跳到
任意(i2,j2)且符合k>=(i1-i2)*(i1-i2)+( j1-j2)*( j1-j2)。
二、每次你至少要向右走一格,也就是说你不能跳到同一列的格子上戒者往回跳。再换句话说就是依次跳
到的位置的坐标中,j 必须是递增的。
每个格子里边有一个分值,当你跳到那里就可以获取到该格子的分数。
现在请你求出你最多能得多少分?
现在假设有一个5×6 的格子,你的弹跳能力为4,则如图所示你能得到17 分。

跳跃路径为(4,1)->(3,2)->(3,4)->(4,5)->(4,6)->跳出格子。



输入格式
第一行包含一个整数T,表示T 个case。
每个case 第一行包含n m k 三个整数(1<=n,m,k<=100)
接下来n行,每行m个分值,格子里的分数的绝对值小于20000


输出格式
输出最大得分。


输入样例
1
5 6 4
1 2 -1 2 1 1
2 3 -1 2 3 1
3 4 -1 2 2 3
4 2 -1 1 3 4
3 1 -1 1 1 4


输出样例
17


提示


来源 Oyy 

题解:

其实这题就是一个深度有限搜索,很简单,需要注意的地方是这题的时间非常非常有限,是非常非常有限。

首先要使用记忆化搜索,使用了记忆化搜索之后还要尽量必要变量的重复声明所消耗的时间,还要逻辑判断所消耗的时间

AC代码:

#ifdef local
#include    <ctime>
#endif
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define rep(i,e) for(int i=0;i<e;i++)
#define rep1(i,e) for(int i=1;i<=e;i++)
#define repx(i,x,e) for(int i=x;i<=e;i++)
#define ll long long
#define pii pair<int,int>
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define test(a) cout<<a<<endl
#define test2(a,b) cout<<a<<" "<<b<<endl
#define test3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
typedef unsigned long long ull;
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;
int k;
int n, m;
int w[110][110];
template <class T>
inline bool scan_d(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF)return 0;
	while (c != '-' && (c < '0' || c > '9'))c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0' && c <= '9')ret = ret * 10 + (c - '0');
	ret = ret * sgn;
	return 1;
}
int dp[110][110];
int vis[110][110];
int dfs(int x, int y) {
	if (y  == m - 1)
		return w[x][y];
	if (vis[x][y])
		return dp[x][y];
	int maxn = -inf;
	vis[x][y]=1;
	for (int i = 0; i <n; i++) {
		for (int j = y + 1; j <m; j++) {
			if (k >= (i - x) * (i - x) + (y - j) * (y - j)) {
				maxn = max(maxn, dfs(i, j));
			}
		}
	}
	dp[x][y] = maxn + w[x][y];
	return dp[x][y];
}

int main() {

	int t;
	scd(t);
	while (t--) {
		scd(n);
		scd(m);
		scd(k);
		mset(dp, 0);
		mset(vis,0);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				scd(w[i][j]);
			}
		}
		int   ans = -inf;
		for (int i = 0; i < n; 	i++)
		{
			ans = max(ans, dfs(i, 0));
		}
		printf("%d\n", ans);
	}

}

超时代码:

#ifdef local
#include    <ctime>
#endif
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define rep(i,e) for(int i=0;i<e;i++)
#define rep1(i,e) for(int i=1;i<=e;i++)
#define repx(i,x,e) for(int i=x;i<=e;i++)
#define ll long long
#define pii pair<int,int>
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define test(a) cout<<a<<endl
#define test2(a,b) cout<<a<<" "<<b<<endl
#define test3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
typedef unsigned long long ull;
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;
int k;
int n, m;
int w[110][110];
template <class T>
inline bool scan_d(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF)return 0;
	while (c != '-' && (c < '0' || c > '9'))c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0' && c <= '9')ret = ret * 10 + (c - '0');
	ret = ret * sgn;
	return 1;
}
bool isCheck(int x , int y , int dx, int dy) {
	if (k >= (dx - x) * (dx - x) + (dy-y) * (dy-y)) {
		return true;
	} else {
		return false;
	}
}
int dp[110][110];
int vis[110][110];
int dfs(int x, int y) {
	if (y  == m - 1)
		return w[x][y];
	if (dp[x][y])
		return dp[x][y];
	int maxn = -inf;
	int temp = 0;
	int pos = 0;
	for (int i = 0; i < n; i++) {
		for (int j = y+1; j <m; j++) {
			if (isCheck(x, y, i, j)) {
				temp = dfs(i, j);
				maxn = max(maxn, temp);
			}
		}
	}
	dp[x][y] = maxn + w[x][y];
	return dp[x][y];
}

int main() {
#ifdef local
	freopen("in.txt", "r", stdin);
	freopen("out", "w", stdout);
	clock_t t_begin = clock();
#endif
	int t;
	scd(t);
	while (t--) {
		scd(n);
		scd(m);
		scd(k);
		mset(dp, 0);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				scd(w[i][j]);
			}
		}
		int   ans = -inf;
		for (int i = 0; i < n; 	i++)
		{
			ans = max(ans, dfs(i, 0));
		}
		printf("%d\n", ans);
	}
#ifdef local
	clock_t t_end = clock();
	double time = (t_end - t_begin) / (double)(CLOCKS_PER_SEC);
	printf("\n\n\nTime_used=%.10lf", time);
#endif
}

可以看出代码基本上一直但是为什么会超时呢?

bool isCheck(int x , int y , int dx, int dy) {
	if (k >= (dx - x) * (dx - x) + (dy-y) * (dy-y)) {
		return true;
	} else {
		return false;
	}
}

这段代码一次产生4个新的变量,变量的产生是需要时间的。所以超时,只要去掉这段代码就可以过了,如果不可以,就继续删减逻辑判断和变量声明的代码。输入挂似乎也会导致超时,所以我没有使用。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值