昨晚第一次做acm的问题,去到浙大的acm网站http://acm.zju.edu.cn/problems.php,先做了1001,其实那是个样板题,直接用加号就行。非常简单。
然后顺着去做1002,想了好一会,终于写了出来,可是在自己的机子都调试不通过。没办法,只有继续调试,分析。
我用的算法是递归,如果某个位置不是墙壁,那可以放房子或者不放,这就是两种做法,对于每种做法,分别计算他们最多可以放的房子数目,然后比较两者谁大。 大者就是答案。
而不放房子时,他的最大房子数,就是紧跟下一个位置可以放房子的最大数。
如果可以放房子时,他的最大房子数,就是紧跟下一个位置可以放房子的最大数加上一。
每个位置在递归时,先分析不放房子的情况,然后再恢复现场,再分析放房子的情况。
具体代码如下:
#include
<
stdio.h
>
void resume( int city[ 4 ][ 4 ], int saved[ 4 ][ 4 ], int i, int j, int n)
... {
for(;i < n; i++)
...{
for(; j < n; j++)
...{
city[i][j] = saved[i][j];
}
j = 0;
}
}
bool isable( int city[ 4 ][ 4 ], int i, int j)
... {
int k;
if(city[i][j] == 2)
return 0;
for(k = i; k >= 0; k--)
if(city[k][j] == 1)
return 0;
else if(city[k][j] == 2)
break;
for(k = j; k >= 0; k--)
if(city[i][k] == 1)
return 0;
else if(city[i][k] == 2)
break;
return 1;
}
int tosearch( int city[ 4 ][ 4 ], int saved[ 4 ][ 4 ], int i, int j, int n)
... {
int sum0 =0, sum1 = 0;
if(j < n - 1)
sum0 = tosearch(city, saved, i, j+1, n);
else if(i < n - 1)
sum0 = tosearch(city, saved, i + 1, 0, n);
resume(city, saved, i, j, n);
if(isable(city, i, j))
...{
city[i][j] = 1;
if(j < n - 1)
sum1 = tosearch(city, saved, i, j+1, n);
else if(i < n - 1)
sum1 = tosearch(city, saved, i + 1, 0, n);
sum1++;
}
if(sum0 > sum1)
return sum0;
return sum1;
}
int main()
... {
int n, i, j, maxsum;
char ch;
int city[4][4], searched[4][4];
scanf("%d", &n);
while(n)
...{
//input city
scanf("%c", &ch);
for(i = 0; i < n; i++)
...{
for(j = 0; j < n; j++)
...{
scanf("%c", &ch);
if(ch == 'X')
...{
city[i][j] = 2;
searched[i][j] = 2;
}
else
...{
city[i][j] = 0;
searched[i][j] = 0;
}
}
scanf("%c", &ch);
}
//solve the problem
maxsum = tosearch(city, searched, 0, 0, n);
printf("%d ", maxsum);
scanf("%d", &n);
}
return 0;
}
void resume( int city[ 4 ][ 4 ], int saved[ 4 ][ 4 ], int i, int j, int n)
... {
for(;i < n; i++)
...{
for(; j < n; j++)
...{
city[i][j] = saved[i][j];
}
j = 0;
}
}
bool isable( int city[ 4 ][ 4 ], int i, int j)
... {
int k;
if(city[i][j] == 2)
return 0;
for(k = i; k >= 0; k--)
if(city[k][j] == 1)
return 0;
else if(city[k][j] == 2)
break;
for(k = j; k >= 0; k--)
if(city[i][k] == 1)
return 0;
else if(city[i][k] == 2)
break;
return 1;
}
int tosearch( int city[ 4 ][ 4 ], int saved[ 4 ][ 4 ], int i, int j, int n)
... {
int sum0 =0, sum1 = 0;
if(j < n - 1)
sum0 = tosearch(city, saved, i, j+1, n);
else if(i < n - 1)
sum0 = tosearch(city, saved, i + 1, 0, n);
resume(city, saved, i, j, n);
if(isable(city, i, j))
...{
city[i][j] = 1;
if(j < n - 1)
sum1 = tosearch(city, saved, i, j+1, n);
else if(i < n - 1)
sum1 = tosearch(city, saved, i + 1, 0, n);
sum1++;
}
if(sum0 > sum1)
return sum0;
return sum1;
}
int main()
... {
int n, i, j, maxsum;
char ch;
int city[4][4], searched[4][4];
scanf("%d", &n);
while(n)
...{
//input city
scanf("%c", &ch);
for(i = 0; i < n; i++)
...{
for(j = 0; j < n; j++)
...{
scanf("%c", &ch);
if(ch == 'X')
...{
city[i][j] = 2;
searched[i][j] = 2;
}
else
...{
city[i][j] = 0;
searched[i][j] = 0;
}
}
scanf("%c", &ch);
}
//solve the problem
maxsum = tosearch(city, searched, 0, 0, n);
printf("%d ", maxsum);
scanf("%d", &n);
}
return 0;
}