最近做的一些深搜题目
关于一些深搜的题目,有很多是按照
碧海潮升的小屋
里面介绍的一些排列组合算法做的,那里面对递归组合介绍的很好
zoj2412
一个普通的深度优先搜索,我的代码比较啰嗦,嘿嘿,反正多一点不要钱
zoj 1694
一个比较有意思的DFS
对 "当前目标是否要划开" 做一个递归
然后对已经出现比目标大的情况剪枝就是可以了
<本题使用STL>
碧海潮升的小屋
里面介绍的一些排列组合算法做的,那里面对递归组合介绍的很好
zoj2412
一个普通的深度优先搜索,我的代码比较啰嗦,嘿嘿,反正多一点不要钱
#include <iostream>
#include <string.h>
using namespace std;
char map[51][51];
char status[51][51];
int n,m;
int ok(int x,int y,char z)
{
int a,b,c,d;
a = b = c = d = 0;
switch(map[x][y])
{
case 'A':
a=d=1;
break;
case 'B':
a=b=1;
break;
case 'C':
d=c=1;
break;
case 'D':
b=c=1;
break;
case 'E':
a=c=1;
break;
case 'F':
b=d=1;
break;
case 'G':
a=b=d=1;
break;
case 'H':
a=c=d=1;
break;
case 'I':
b=c=d=1;
break;
case 'J':
a=b=c=1;
break;
case 'K':
a=b=c=d=1;
break;
}
if(z=='a'&&a==1) return 1;
else if(z=='b'&&b==1) return 1;
else if(z=='c'&&c==1) return 1;
else if(z=='d'&&d==1) return 1;
else
return 0;
}
void chuandfs(int x,int y)
{
int a,b,c,d;
a = b = c = d = 0;
switch(map[x][y])
{
case 'A':
a=d=1;
break;
case 'B':
a=b=1;
break;
case 'C':
d=c=1;
break;
case 'D':
b=c=1;
break;
case 'E':
a=c=1;
break;
case 'F':
b=d=1;
break;
case 'G':
a=b=d=1;
break;
case 'H':
a=c=d=1;
break;
case 'I':
b=c=d=1;
break;
case 'J':
a=b=c=1;
break;
case 'K':
a=b=c=d=1;
break;
}
if(a==1&&x-1>0&&ok(x-1,y,'c')&&status[x-1][y]==0)
{
status[x-1][y] = 1;
chuandfs(x-1,y);
}
if(b==1&&y+1<=m&&ok(x,y+1,'d')&&status[x][y+1]==0)
{
status[x][y+1] = 1;
chuandfs(x,y+1);
}
if(c==1&&x+1<=n&&ok(x+1,y,'a')&&status[x+1][y]==0)
{
status[x+1][y] = 1;
chuandfs(x+1,y);
}
if(d==1&&y-1>0&&ok(x,y-1,'b')&&status[x][y-1]==0)
{
status[x][y-1] = 1;
chuandfs(x,y-1);
}
}
int main()
{
int i,j,cnt;
bool ff;
while(cin >> n >> m)
{
ff = false;cnt = 0;
if(n==-1&&m==-1) break;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
cin >> map[i][j];
memset(status,0,sizeof(status));
while(ff==false)
{
ff = true;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
{
if(status[i][j]==0)
{
ff = false;
status[i][j] = 1;
chuandfs(i,j);
cnt++;
}
}
}
cout << cnt << endl;
}
return 0;
}
#include <string.h>
using namespace std;
char map[51][51];
char status[51][51];
int n,m;
int ok(int x,int y,char z)
{
int a,b,c,d;
a = b = c = d = 0;
switch(map[x][y])
{
case 'A':
a=d=1;
break;
case 'B':
a=b=1;
break;
case 'C':
d=c=1;
break;
case 'D':
b=c=1;
break;
case 'E':
a=c=1;
break;
case 'F':
b=d=1;
break;
case 'G':
a=b=d=1;
break;
case 'H':
a=c=d=1;
break;
case 'I':
b=c=d=1;
break;
case 'J':
a=b=c=1;
break;
case 'K':
a=b=c=d=1;
break;
}
if(z=='a'&&a==1) return 1;
else if(z=='b'&&b==1) return 1;
else if(z=='c'&&c==1) return 1;
else if(z=='d'&&d==1) return 1;
else
return 0;
}
void chuandfs(int x,int y)
{
int a,b,c,d;
a = b = c = d = 0;
switch(map[x][y])
{
case 'A':
a=d=1;
break;
case 'B':
a=b=1;
break;
case 'C':
d=c=1;
break;
case 'D':
b=c=1;
break;
case 'E':
a=c=1;
break;
case 'F':
b=d=1;
break;
case 'G':
a=b=d=1;
break;
case 'H':
a=c=d=1;
break;
case 'I':
b=c=d=1;
break;
case 'J':
a=b=c=1;
break;
case 'K':
a=b=c=d=1;
break;
}
if(a==1&&x-1>0&&ok(x-1,y,'c')&&status[x-1][y]==0)
{
status[x-1][y] = 1;
chuandfs(x-1,y);
}
if(b==1&&y+1<=m&&ok(x,y+1,'d')&&status[x][y+1]==0)
{
status[x][y+1] = 1;
chuandfs(x,y+1);
}
if(c==1&&x+1<=n&&ok(x+1,y,'a')&&status[x+1][y]==0)
{
status[x+1][y] = 1;
chuandfs(x+1,y);
}
if(d==1&&y-1>0&&ok(x,y-1,'b')&&status[x][y-1]==0)
{
status[x][y-1] = 1;
chuandfs(x,y-1);
}
}
int main()
{
int i,j,cnt;
bool ff;
while(cin >> n >> m)
{
ff = false;cnt = 0;
if(n==-1&&m==-1) break;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
cin >> map[i][j];
memset(status,0,sizeof(status));
while(ff==false)
{
ff = true;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
{
if(status[i][j]==0)
{
ff = false;
status[i][j] = 1;
chuandfs(i,j);
cnt++;
}
}
}
cout << cnt << endl;
}
return 0;
}
zoj 1694
一个比较有意思的DFS
对 "当前目标是否要划开" 做一个递归
然后对已经出现比目标大的情况剪枝就是可以了
<本题使用STL>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> num;
vector<int> rcd(15);
vector<int> minsum(15);
int pos = 0,mpos;
int len,minval,n;
bool ff;
void chuandfs(int p,int sum,int cur)
{
if(sum+cur>n)//如果已经比目标数大了,那么剪枝
return;
if(p<len)//如果层数少于LEN,则每次分两种情况讨论
{
rcd[pos++] = cur*10 + num[p];
chuandfs(p+1,sum+cur*10+num[p],0);
rcd[pos--] = 0;
if(p!=len-1)//如果已经到底了,那么就不用这种情况了
chuandfs(p+1,sum,cur*10+num[p]);
}
else
{
sum += cur;
if(sum==minval)//当前最接近值已经出现过
{
ff = true;
}
if(sum<=n&&sum>minval)//出现新的最接近值
{
minval = sum;
ff = false;
mpos = pos;
for(int x=0;x<pos;++x)//将当前最接近值保存起来
minsum[x] = rcd[x];
if(cur!=0)//另一种情况
{
minsum[pos] = cur;
mpos++;
}
/*cout << "key is :" << minval << endl;*/
}
return;
}
}
int main()
{
int m,i,t;
while(cin >> n)
{
if(n==0)
break;
cin >> m;
num.clear();
t = 0;
if(m==n)
{
cout << n << " " << n << endl;
continue;
}
while(m>0)
{
num.push_back(m%10);
t += m%10;
m /= 10;
}
if(t>n)
{
cout << "error" << endl;
continue;
}
len = num.size();
for(i=0;i<len/2;++i)
std::swap(num[i],num[len-i-1]);
minval = 0;
ff = false;
chuandfs(0,0,0);
if(ff == true)
{
cout << "rejected" << endl;
continue;
}
if(minval<0) minval*=-1;
cout << minval;
for(int x=0;x<mpos;++x)
{
cout << " " << minsum[x];
}
cout << endl;
}
}
#include <vector>
#include <algorithm>
using namespace std;
vector<int> num;
vector<int> rcd(15);
vector<int> minsum(15);
int pos = 0,mpos;
int len,minval,n;
bool ff;
void chuandfs(int p,int sum,int cur)
{
if(sum+cur>n)//如果已经比目标数大了,那么剪枝
return;
if(p<len)//如果层数少于LEN,则每次分两种情况讨论
{
rcd[pos++] = cur*10 + num[p];
chuandfs(p+1,sum+cur*10+num[p],0);
rcd[pos--] = 0;
if(p!=len-1)//如果已经到底了,那么就不用这种情况了
chuandfs(p+1,sum,cur*10+num[p]);
}
else
{
sum += cur;
if(sum==minval)//当前最接近值已经出现过
{
ff = true;
}
if(sum<=n&&sum>minval)//出现新的最接近值
{
minval = sum;
ff = false;
mpos = pos;
for(int x=0;x<pos;++x)//将当前最接近值保存起来
minsum[x] = rcd[x];
if(cur!=0)//另一种情况
{
minsum[pos] = cur;
mpos++;
}
/*cout << "key is :" << minval << endl;*/
}
return;
}
}
int main()
{
int m,i,t;
while(cin >> n)
{
if(n==0)
break;
cin >> m;
num.clear();
t = 0;
if(m==n)
{
cout << n << " " << n << endl;
continue;
}
while(m>0)
{
num.push_back(m%10);
t += m%10;
m /= 10;
}
if(t>n)
{
cout << "error" << endl;
continue;
}
len = num.size();
for(i=0;i<len/2;++i)
std::swap(num[i],num[len-i-1]);
minval = 0;
ff = false;
chuandfs(0,0,0);
if(ff == true)
{
cout << "rejected" << endl;
continue;
}
if(minval<0) minval*=-1;
cout << minval;
for(int x=0;x<mpos;++x)
{
cout << " " << minsum[x];
}
cout << endl;
}
}
浙公网安备 33010602011771号