您的位置:首页 > 其它

南邮 OJ 1418 清扫

2015-08-05 15:37 471 查看


清扫

时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte

总提交 : 16 测试通过 : 13

比赛描述

现在要打扫国王的牧圈。已经30年没打扫了。所以这次的计划是用河水来冲。

牧圈排成整齐的格子,每相邻的两个之间都有门。要想让水进去,就必须打开这些门。这不是件容易的事情。因为有些圈里土堆得很高。因此打开门就很费劲。为了使花的力气最小,总是把门推向土低的一边。你的任务是计算最少得费多少劲。我们用土的厚度来描述这个值。

输入

第一行是宽度w和高度h,其中3 <= w,h <= 40。以下h行数据,描述了土的高度,也就是我们所浪费体力的度量。数据的范围在1到100之间。

输出

你得到的结果。所有的格子都必须进水。水是从左上角的格子进去的。

样例输入

4 3

3 5 2 1

7 3 4 8

1 6 5 7

样例输出

26

提示

题目来源

JSOI2010

/* Wrong Answer at Test 1
#include<iostream>
#define MAX_N 40
int a[MAX_N][MAX_N];
int main(){
int i,j,n,m,cost;
scanf("%d%d",&m,&n);
for(i=0;i<n;i++){
for(j=0;j<m;j++){
scanf("%d",&a[i][j]);
}
}
cost = 0;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if( i-1>=0 && a[i][j]<a[i-1][j] ||
i+1<n  && a[i][j]<a[i+1][j] ||
j-1>=0 && a[i][j]<a[i][j-1] ||
j+1<m  && a[i][j]<a[i][j+1]){
continue;
}
cost += a[i][j];
}
}
if(a[0][0]>=a[0][1] && a[0][0]>=a[1][0]){
cost -= a[0][0];
}
printf("%d\n",cost);
}
*/

/* AC 27MS Internet
#include<iostream>
#define N 40
using namespace std;

int w,h,n;
int map[N*N][N*N];
int a

;
int dis[N*N];
bool v[N*N]={0};

void Init(){
int i,j;
scanf("%d%d",&w,&h);
n = w*h;
for( i=0;i<n;i++){
for(j=0;j<n;j++){
map[i][j] = INT_MAX;
}
}
for( i=0;i<h;i++){
for( j=0;j<w;j++){
scanf("%d",&a[i][j]);
if( i>0 ){
map[i*w+j][(i-1)*w+j]=
map[(i-1)*w+j][i*w+j]=
min(a[i][j],a[i-1][j]);
}
if( j>0 ){
map[i*w+j][i*w+j-1]=
map[i*w+j-1][i*w+j]=
min(a[i][j],a[i][j-1]);
}
}
}
}

void Prim(){
int i,j,k,min,ans=0;
for( i=0;i<n;i++){
dis[i]=map[1][i];
}
v[1]=1;
for( i=0;i<n;i++){
min = INT_MAX;
for( j=0;j<n;j++){				//可优化:用堆或者map存放距离,连接上的删除
if(!v[j] && dis[j]<min){
min=dis[j];
k=j;
}
}
v[k]=1;
for( j=0;j<n;j++){				//可优化:只判断与k相邻的4点
if(!v[j] && dis[j]>map[k][j]){
dis[j]=map[k][j];
}
}
}
for( i=0;i<n;i++){
if(dis[i]!=INT_MAX){
ans+=dis[i];
}
}
printf("%d\n",ans);
}

int main(){
Init();
Prim();
return 0;
}
*/

// AC 11MS
#include<iostream>
using namespace std;

#define N 40
int a

;
int d

;
bool v

;
int dirX[4]={-1, 1, 0, 0};
int dirY[4]={ 0, 0,-1, 1};

int main(){
//	freopen("test.txt","r",stdin);
int w,h,i,j;
scanf("%d%d",&w,&h);
for(i=0;i<h;i++){
for(j=0;j<w;j++){
scanf("%d",&a[i][j]);
d[i][j] = INT_MAX;
}
}
d[0][0] = 0;
int k,t=w*h,r=0,x,y,minV,s,dij;
for(k=1;k<=t;k++){
minV = INT_MAX;
for(i=0;i<h;i++){	//时间瓶颈在这
for(j=0;j<w;j++){
if(!v[i][j] && minV > d[i][j]){
minV = d[i][j];
x = i;
y = j;
}
}
}
v[x][y] = 1;		//[x][y]为新加进来的点
r += d[x][y];
for(s=0;s<4;s++){	//更新邻居的距离信息
i = x+dirX[s];
j = y+dirY[s];
if(i>=0 && i<h && j>=0 && j<w && !v[i][j]){
dij = min(a[x][y],a[i][j]);
if(d[i][j]>dij){
d[i][j] = dij;
}
}
}
}
printf("%d\n",r);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: