在准备蓝桥杯,最重要的当然是搜索啦啦,开个搜索专题专门贴题,不定时更新。
hdu 2181 哈密顿绕行世界问题
因为数据不大,所以简单的深搜就可以了,注意从小到大排下序,防止数据随机给。
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
using namespace std;
vector<int> v[21];
int book[21];
int ttime;
int temp[23];
int m;
void dfs(int s,int t);
int main(){
for(int i=1;i<=20;i++){
for(int j=0;j<3;j++){
int x;
scanf("%d",&x);
v[i].push_back(x);
}
//这里应该排序
}
scanf("%d",&m);
while(m){
ttime = 0;
memset(book,0,sizeof(book));
temp[0] = m;
book[m] = 1;
dfs(m,0);
scanf("%d",&m);
}
return 0;
}
void dfs(int s,int t){
if(t==19){
int status = 0;
for(int i=0;i<v[s].size();i++){
if(v[s][i]==m){//注意是环
status = 1;
temp[t+1] = m;
break;
}
}
if(status){
printf("%d: ",++ttime);
for(int i=0;i<=t+1;i++){
printf("%d",temp[i]);
if(i!=t+1) printf(" ");
else printf("\n");
}
}
return ;
}
for(int i=0;i<v[s].size();i++){
if(book[v[s][i]]==0){
book[v[s][i]] = 1;
temp[t+1] = v[s][i];
dfs(v[s][i],t+1);
book[v[s][i]] = 0;
}
}
}
nyoj 1336 火车进栈
这题是卡特兰数,但是因为数据量小的原因,就用dfs做了。
每深搜一个排列,则模拟进栈,看是否符合。algorithm头文件里有bool next_permutation( iterator start, iterator end ); 全排列函数,会对该排列进行下一个排列,若不存在下一个排列,则返回false。这样其实就不用深搜了。
#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<vector>
using namespace std;
int book[23];
int temp[23];
int N;
int time;
int check();
void dfs(int t);
int main(){
while(scanf("%d",&N)!=EOF){
memset(book,0,sizeof(book));
time = 0;
dfs(0);
}
return 0;
}
//模拟进栈
int check(){
stack<int>s;
vector<int >v;
int t = 0;
for(int i=1;i<=N;i++){
while(!s.empty()&&s.top()==temp[t]){
v.push_back(s.top());
s.pop();
t++;
}
if(i==temp[t]){
v.push_back(i);
t++;
}
else{
s.push(i);
}
while(!s.empty()&&s.top()==temp[t]){
v.push_back(s.top());
s.pop();
t++;
}
}
for(int i=0;i<N;i++){
if(v[i]!=temp[i]) return 0;
}
return 1;
}
//搜出全排列
void dfs(int t){
if(t==N){
int status = check();
if(status&&time<20){
time++;
for(int i=0;i<N;i++){
printf("%d",temp[i]);
}
printf("\n");
}
return ;
}
for(int i=1;i<=N;i++){
if(book[i]==0){
temp[t] = i;
book[i] = 1;
dfs(t+1);
if(time>=20) return ;
book[i] = 0;
}
}
}
方老师与素数 851 (Prime Path poj 3126 题目一样)
我用了最朴素最朴素的bfs,跑了500ms+……
搜出当前剩下的素数与该节点有一个数不同,搜到终点结束就可以了,贴一份我自己的和大神的代码。。。
弱弱我的
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<vector>
#include<list>
#include<algorithm>
#include<queue>
using namespace std;
vector<int>p;
int step;
struct node{
int x;
int s;
};
int bfs(int s,int e);
void init();
int main(){
init();
int n,m;
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
step = 0;
int s = bfs(n,m);
if(s){
printf("%d\n",step);
}
else{
printf("Impossible\n");
}
}
return 0;
}
int bfs(int s,int e){
queue<node>q;
vector<int>v(p.size(),0);
node n;
n.x = s;
n.s = 0;
q.push(n);
for(int i=0;i<p.size();i++){
if(n.x==p[i]){
v[i] = 1;
}
}
while(!q.empty()){
node temp = q.front();
q.pop();
if(temp.x==e){
step = temp.s;
return 1;
}
for(int i=0;i<p.size();i++){
if(v[i]==0){
if(temp.x/1000!=p[i]/1000&&temp.x%1000==p[i]%1000){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
else if(temp.x/1000==p[i]/1000&&(temp.x%1000)/100!=(p[i]%1000)/100&&temp.x%100==p[i]%100){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
else if(temp.x/100==p[i]/100&&(temp.x%100)/10!=(p[i]%100)/10&&temp.x%10==p[i]%10){
v[i] = 1;
node t;
t.x = p[i];
t.s = temp.s+1;
q.push(t);
}
else if(temp.x/10==p[i]/10&&temp.x%10!=p[i]%10){
v[i] = 1;
node t;