NOIP 2004 普及组 复赛 peanuts 花生采摘
1.借助题图,看懂题意,道路只有一条。
2.在有一定距离的两株之间跳转,原以为要用什么高深算法,模拟了一下,无论怎么跳,步数都可以归结为|r2-r1|+|c2-c1|。省去很多麻烦。
3.采用结构题存储数据,按花生数自大到小排序。
4.采摘下一株时,要判定采下下一株并且回到路边步数是否够用,若够用,采,若不够用,结束。
5.考虑包括,可能第一株都无法采摘。花生不够采。花生全部采完。三种情况。
6.程序编制过程中,处理行列颠倒了,折腾了会,但是跟踪程序还是查了出来。
7.信心满满,提交,没想到第4个测试点WA。根据提交的数据,还是行列颠倒程序修改不全造成的。if(2*nut[0].r+1>k){//此处写成 2*nut[0].c+1>k查了好半天
8.该题涉及的问题都考虑到了,出错的原因行列颠倒修改不全。
附上AC代码,编译环境Dev-C++4.9.9.2
#include <stdio.h>
#include <stdlib.h>
struct node{
int r;//行
int c;//列
int p;//花生数目
}nut[900],nut_t;
int main(){
int m,n,k;
int i,j,v;
int count=0;
int num=0;
scanf("%d%d%d",&m,&n,&k);
for(i=1;i<=m;i++)
for(j=1;j<=n;j++){
scanf("%d",&v);
if(v>0){
nut[count].r=i;
nut[count].c=j;
nut[count].p=v;
count++;
}
}
for(i=0;i<count;i++)//冒泡排序,自大到小
for(j=i+1;j<count;j++)
if(nut[i].p<nut[j].p){
nut_t=nut[i];
nut[i]=nut[j];
nut[j]=nut_t;
}
//采摘第一株
if(2*nut[0].r+1>k){//此处写成 2*nut[0].c+1>k查了好半天
printf("%d\n",num);
return 0;
}
else{
k=k-nut[0].r-1;
num+=nut[0].p;
}
for(i=1;i<count;i++)
if((abs(nut[i].r-nut[i-1].r)+abs(nut[i].c-nut[i-1].c)+1+nut[i].r)<=k){///可以采摘
k=k-(abs(nut[i].r-nut[i-1].r)+abs(nut[i].c-nut[i-1].c)+1);
num+=nut[i].p;
}else//采摘不到
break;
printf("%d\n",num);
return 0;
}