home on the range——优化与图形动态规划

Home on the Range

 家的范围
农民约翰在一片边长是N (2 <= N <= 250)英里的正方形牧场上放牧他的奶牛。
(因为一些原因,他的奶牛只在正方形的牧场上吃草。)
遗憾的是,他的奶牛已经毁坏一些土地。( 一些1平方英里的正方形)
农民约翰需要统计那些可以放牧奶牛的正方形牧场(至少是2x2的,在这些较大的正方形中没有小于1x1的部分被分割毁坏)。
你的工作要在被供应的数据组里面统计所有不同的正方形放牧区域(>2x2)的个数。
当然,放牧区域可能是重叠。

PROGRAM NAME: range

INPUT FORMAT

第 1 行:

  N,牧区的边长。

第 2 到 n+1行:

N个没有空格分开的字符。

0 表示 "那一个区段被毁坏了";1 表示 " 准备好被吃"。

SAMPLE INPUT (file range.in)
6
101111
001111
111111
001111
101101
111001

OUTPUT FORMAT
输出那些存在的正方形的大小和个数,一种一行。

SAMPLE OUTPUT (file range.out)
2 10
3 4
4 1
 

程序最初思想:设置数字f[k][i][j],k为正方形边长,i和j是正方形右下角的顶点坐标。a[i][j]存储0-1矩阵。

1.初始化:f[1][i][j]=a[i][j].

2.然后判断f[k-1][i-1][j-1]可否得到(边长为k-1的小正方形),如果可以,再在该正方形周围加一圈,就

是边长为k的正方形。

3.再判断这一圈中是否有0,有则f[k][i][j]=0;否则f[k][i][j]=1.

思想没错,但是第三步不得不用循环逐一判断,显然效率不高。而且,这也不是典型的动态规划的算法。

动态规划:第二与第三步变成了:

if(f[k-1][i-1][j]&&f[k-1][i][j-1]&&f[k-1][i-1][j-1]&&f[k-1][i][j])

f[k][i][j]=1;

else f[k][i][j]=0;

也就是判断边长为k的正方形的四个角上边长为k-1的正方形能否得到。另外可以减维。

 

 

代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 int f[251][251],n;
4 int sum[251]={0};
5 char a[251];
6
7 int main(){
8 FILE *in,*out;
9 in=fopen("input6.txt","r");
10 out=fopen("output.txt","w");
11 int i,j,k,x,flag;
12
13 fscanf(in,"%d",&n);
14 for(i=1;i<=n;i++)
15 {
16 fscanf(in,"%s",a);
17 for(j=1;j<=n;j++)
18 f[i][j]=a[j-1]-'0';
19 }
20
21 for(k=2;k<=n;k++)
22 for(i=n;i>=k;i--)————循环要倒写
23 for(j=n;j>=k;j--)
24 {
25 if(f[i][j-1]&&f[i][j]&&f[i-1][j-1]&&f[i-1][j])
26 {
27 f[i][j]=1;
28 sum[k]++;
29 }
30 else f[i][j]=0;
31 }
32
33 for(i=2;i<=n;i++)
34 if(sum[i])
35 fprintf(out,"%d %d\n",i,sum[i]);
36 fclose(in);
37 fclose(out);
38 return 0;
39 }
40

总结:需要认真思考如何优化程序;在找状态方面稍有进步。继续努力啊。

posted @ 2010-07-26 22:52  Danty  阅读(269)  评论(0编辑  收藏  举报