Mr. Robinson and his pet monkey Dodo love peanuts very much. One day while they were having a walk on a country road, Dodo found a sign by the road, pasted with a small piece of paper, saying "Free Peanuts Here! " You can imagine how happy Mr. Robinson and Dodo were.
There was a peanut field on one side of the road. The peanuts were planted on the intersecting points of a grid as shown in Figure-1. At each point, there are either zero or more peanuts. For example, in Figure-2, only four points have more than zero peanuts, and the numbers are 15, 13, 9 and 7 respectively. One could only walk from an intersection point to one of the four adjacent points, taking one unit of time. It also takes one unit of time to do one of the following: to walk from the road to the field, to walk from the field to the road, or pick peanuts on a point.
According to Mr. Robinson's requirement, Dodo should go to the plant with the most peanuts first. After picking them, he should then go to the next plant with the most peanuts, and so on. Mr. Robinson was not so patient as to wait for Dodo to pick all the peanuts and he asked Dodo to return to the road in a certain period of time. For example, Dodo could pick 37 peanuts within 21 units of time in the situation given in Figure-2.
Your task is, given the distribution of the peanuts and a certain period of time, tell how many peanuts Dodo could pick. You can assume that each point contains a different amount of peanuts, except 0, which may appear more than once.
Input
The first line of input contains the test case number T (1 <= T <= 20). For each test case, the first line contains three integers, M, N and K (1 <= M, N <= 50, 0 <= K <= 20000). Each of the following M lines contain N integers. None of the integers will exceed 3000. (M * N) describes the peanut field. The j-th integer X in the i-th line means there are X peanuts on the point (i, j). K means Dodo must return to the road in K units of time.
Output
For each test case, print one line containing the amount of peanuts Dodo can pick.
Sample Input
2
6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0
6 7 20
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0
Sample Output
37
28
解题思路:
这个题确实是有点麻烦。。不过是实际生活中的问题。。。仔细看。。脑子不要晕。。不要少想情况。。不要少加。。
而且因为要记录的变量比较多,所以自己设变量一定要把名字写好。。不要混。。记住每个变量表示的是啥,什么时候该加1。。下面代码注释中每一步写的很详细。。不多说。。
将花生田模拟成一个矩阵,然后在矩阵中进行相应的操作。通过分析,此矩阵包括横、纵坐标,还有相应位置花生的数目。 特别注意的是每次加完当前最大花生数目后还要把最大花生下标的数目清零 1.判断采摘时间 当结束一个采摘动作后,寻找花生田中下一个花生最多的位置。通过剩余时间,判断是否能从现在位置到达下一个花生个数最多的位置,完成采摘以及返回,如果时间不够则退出采摘。 2.寻找花生个数最多的位置 由于矩阵不会很大,因此采取遍历矩阵的算法。遍历矩阵中所有的元素,找到当前花生个数最大的然后记录下它的行列下标,以及花生个数。直到遍历整个矩阵结束。具体方法为采用二维数组遍历的形式,外循环为行,内循环为列,如果发现个数较多的时候,交换数值。 3.如何进行矩阵的初始化(起始坐标左上角设为[0][0]还是[1][1]) 由题意分析可得,从地里到路上还需要1个单位时间,图中的坐标又都是从1开始,所以若用[1][1]对应花生地的左上角,则从矩阵中[i][j]点,回到路上所需时间就是i,这样更便于理解,不易出错。 代码如下。。。因为最后一部分少加1调了好半天。。瓦特了。。。
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAXN 51 //矩阵的最大行列值
int main()
{
int now_i,now_j;
//定义矩阵中当前的位置
int time_limit,a_i,a_j,T;
//定义时间限制,输入的矩阵的行列大小
int i,j;
int a[MAXN][MAXN];
//填入花生的数量
int peanuts_count;
//采摘到的花生数量
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d",&a_i,&a_j,&time_limit);
peanuts_count = 0;
for(i = 1;i <= a_i;i++) //注意往矩阵填数的时候下标从1开始
{
for(j = 1;j <= a_j;j++)
{
scanf("%d",&a[i][j]);
}
}
now_i = 0;
now_j = 0;
int num_peanuts = 0;
int max_i = 0,max_j = 0;
//最多花生的横纵坐标的位置
int max_peanuts = 0;
//最多的花生的数量
int time_count = 0;
//当前所花费的时间
while(time_count < time_limit)
{
//time_count = 0;
max_peanuts = 0;//将最多的花生重置清零
//遍历矩阵,挑选花生个数最多的,记录下当前下标以及花生个数
for(i = 1;i <= a_i;i++)
{
for(j = 1;j <= a_j;j++)
{
if(max_peanuts < a[i][j])
{
max_peanuts = a[i][j];
max_i = i;
max_j = j;
}
}
}
if(max_peanuts == 0) //花生田里没有花生
break;
if(now_i == 0)
now_j = max_j;
//如果此时还在大路上,则让其当前的纵坐标和最多花生的纵坐标相同,那么就可以出发时最近,所花时间最短
if((time_count+max_i+abs(now_i-max_i)+abs(now_j-max_j) + 1)<= time_limit)
//当前所花费的时间 +从最大花生处返回大路时的横坐标+当前位置与最大花生的横坐标的差+当前位置与最大花生处的纵坐标的差
{
time_count = time_count+abs(now_i-max_i)+abs(now_j-max_j) + 1;//返回大路还要单位时间1
now_i = max_i;
now_j = max_j;
peanuts_count = peanuts_count + max_peanuts;
a[max_i][max_j] = 0;//因为已经加完,所以把最大下标位置处的花生数清零
}
else
break;
}
printf("%d\n",peanuts_count);
}
return 0;
}