2018.4.20
UVA572 油田 看了刘汝佳老师的紫皮书上的例题,应该是用了一种叫做洪水填充或者种子填充的算法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[101][101];
int visit[101][101];
int m,n;
void dfs(int r,int c,int cnt)
{
if(r<0 || r >= m || c < 0 || c >= n)return;//超出范围限制
if(visit[r][c] > 0 || s[r][c] != '@')return;//已经访问过或者不是@
visit[r][c] = cnt;
for(int dr = -1; dr <= 1; dr ++)
for(int dc = -1; dc <= 1; dc ++)
if(dc!=0||dr!=0)dfs(r+dr,c+dc,cnt);
}
int main()
{
while(scanf("%d%d",&m,&n) && m && n)
{
for(int i = 0; i < m; i ++)
{
getchar();
for(int j = 0; j < n; j ++)
{
scanf("%c",&s[i][j]);
}
}
memset(visit,0,sizeof(visit));
int cnt = 0;
for(int i = 0; i < m; i ++)
for(int j = 0; j < n; j ++)
if(s[i][j] == '@'&&visit[i][j] == 0)dfs(i,j,++cnt);
cout << cnt << endl;
}
return 0;
}
4.21
HDU1455 sticks 用了剪枝的思想
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100;
int a[maxn],v[maxn];
int p;//判断是否计算出最小值
int m;//输入的木棍个数m
int cmp(int i,int j)
{
return i>j;
}
void dfs(int beg, int len, int aim, int num)//起始下标,木棍长度,目标长度,拼接的木棍总数
{
if(p)return;
if(num == m){
p = 1;
return;
}
for(int i = beg; i < m; i ++)
{
if(a[i] + len <= aim && v[i] != 1)
{
v[i] = 1;
if(a[i]+len == aim)dfs(0,0,aim,num+1);
else{
dfs(i + 1, a[i] + len, aim, num+1);//这是个用num++就超时用++num就WA的地方
}
v[i] = 0;
if(p) return;//完成,返回
if(len == 0)return;//剪枝,如果前面的不满足条件,那么后面的也一定不满足
while(i < m && a[i+1] == a[i]) ++i;//剪枝,若不满足条件,则把不满足条件的长度相等的木棍跳过去
}
}
}
int main()
{
int sum;//所有木棍的总长度
while(cin >> m && m!= 0)
{
memset(v,0,sizeof(v));
sum = 0;
for(int i = 0; i < m; i ++)
{
cin >> a[i];
sum += a[i];
}
sort(a,a+m,cmp);
for(int i = a[0]; i <= sum; i ++)
{
if(i == sum)cout << sum << endl;//如果只有一个木棍,直接输出
else if(sum % i == 0)//剪枝
{
p = 0;
dfs(0,0,i,0);
if(p)
{
cout << i << endl;
break;
}
}
}
}
return 0;
}
4.23
HDU2553 N皇后问题 无论如何都超时,一气之下打了表
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
using namespace std;
int tot,n;
int v[20][20];
void searchs(int r)
{
if(r >= n)
{
tot ++;
return;
}
for(int i = 0; i < n; i ++)
{
if(!v[0][i]&&!v[1][r+i]&&!v[2][r-i+n])
{
v[0][i] = v[1][r+i] = v[2][r-i+n] = 1;
searchs(r+1);
v[0][i] = v[1][r+i] = v[2][r-i+n] = 0;
}
}
}
int main()
{
while(scanf("%d",&n)&&n)
{
// clock_t start,ends;
// start = clock();
tot = 0;
memset(v,0,sizeof(v));
searchs(0);
printf("%d\n",tot);
// ends = clock();
// printf("time:%d\n",ends - start);
}
return 0;
}