解题思路:
1.本道题一定注意审题,是找到花生最多的地方,然后判断是否能采摘,如果可以,再去找剩下的里面花生最多的地方,如果看懂了这里,这道题其实用不着搜索,最优等方案,直接模拟即可
2.首先输入数据,判断每个地方是否有花生,如果有的话,将此处花生的行号,列号,数目存入到结构体数组node中
3.时间是给定的t,除去从路边跳到第一行和从第一行跳回到路边的时间,t=t-2
4.根据花生的数量对结构体数组进行降序排序
5.设置每一步的起点和终点,刚开始的起点比较特殊,行号为第一行,列号和排好序的数组下标位置1的列号相等,意思是直线走即可
6.创建了一个计算时间T的函数,输入目的地的行号和列号,还有此时的位置,如果从当前位置能走到下一步,并且能从目的地回去的话,那么此处的花生可以采摘,花生累加,时间更新(注意这里的时间还是去下一个地方和采摘花生的时间,不减去返回的时间,返回的时间只是用来判断能否回去,必须保证到达一个新地点后,既能采摘完,还得再回到第一行)
7.当发现时间不够用的时候,或者采摘完所有的花生后,退出循环,输出sum
#include<bits/stdc++.h>
using namespace std;
int a[25][25];
struct node{
int x;//该花生的行号
int y;//该花生的列号
int num;//该花生的数目
}mm[1000];
bool cmp(node aa,node bb)
{
return aa.num>bb.num;//花生数量按照降序排序
}
int T(int aa,int bb,int cc,int dd)//计算去下一个地点采摘花生并返回第一行的时间
{
int ans=fabs(aa-cc)+fabs(bb-dd)+1+aa-1;
return ans;
}
int main()
{
int m,n,t,temp=0;
cin>>m>>n>>t;
for(int i=1;i<=m;i++)//输入数据
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
if(a[i][j]!=0)//如果这个地点有花生
{
mm[++temp].x=i;//标记行号
mm[temp].y=j;//标记列号
mm[temp].num=a[i][j];//标记数量
}
}
}
t=t-2;//除去从路边到花生地和花生地到路边的时间
sort(mm+1,mm+temp+1,cmp);//对数量降序排序
int start_x=1,start_y=mm[1].y;//确定起点的行号列号
int flag=1,sum=0;//结构体数组的书签
while(1)
{
if(flag>temp)//如果书签超过总数量
break;//结束循环
if(t-T(mm[flag].x,mm[flag].y,start_x,start_y)>=0)//如果时间够去下一个地方并且还能返回的话
{
sum=sum+mm[flag].num;//加上这个地点的花生数量
t=t-T(mm[flag].x,mm[flag].y,start_x,start_y)+mm[flag].x-1;//时间更新,但是并没有返回到起点
start_x=mm[flag].x;//当前的位置变为起点
start_y=mm[flag].y;
flag++;//书签移动,去下一个点
}
else//如果时间不够去下一个地方采摘并且原路返回的话
break;//结束程序
}
cout<<sum;//输出结果
return 0;
}