Prime Path (BFS)
题意: 求一个素数 a 变换到 一个素数b 的最小次数
变换规则为:变换数的一个数位,然后使得变换后的数为素数;
思路: 这个能想到用bfs真是神奇,先把一个数的数位用一个数组记录,然后对其中的一个数位进行更改,然后判断更改后的数是否为素数,是的话入队;
因为一次只能对一个数位进行操作,所以每次进行更改位上的数的时候记录一下,之后再放回去;
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const ll maxn = 10000 + 10;
#define INF 0x3f3f3f3f
int step[maxn];
bool vis[maxn];
bool is_prime[maxn];
void Init()
{
memset(is_prime,true,sizeof(is_prime));
is_prime[0] = is_prime[1] = false;
for(int i = 2; i < maxn; i ++)
{
for(int j = i *2; j < maxn ; j += i)
{
is_prime[j] = false;
}
}
}
int bfs(int a,int b)
{
memset(step,0,sizeof(step));
memset(vis,false,sizeof(vis));
queue<int>q;
q.push(a);
vis[a] = true;
step[a] = 0;
while(!q.empty())
{
int temp = q.front();
if(temp == b)
{
return step[temp];
}
q.pop();
int t[4];
t[0] = temp/1000;
t[1] = temp/100 % 10;
t[2] = temp/10 %10;
t[3] = temp % 10;
// cout << t[0] << " " << t[1] << " " << t[2] << " " << t[3] << endl;
for(int i = 0; i < 4; i ++)
{
int ts = t[i];
for(int j = 0; j <= 9; j ++)
{
if(j == temp)
continue;
t[i] = j;
int tss = t[0] * 1000 + t[1] * 100 + t[2] * 10 + t[3];
if(!vis[tss] && t[0] != 0 && is_prime[tss])
{
q.push(tss);
vis[tss] = true;
step[tss] = step[temp] + 1;
}
}
t[i] = ts;
}
}
return -1;
}
int main()
{
Init();
int n;
while( ~ scanf("%d",&n))
{
while( n --)
{
int a,b;
scanf("%d%d",&a,&b);
int ans = bfs(a,b);
if(ans == -1)
{
cout << "Impossible" << endl;
}
else cout << ans << endl;
}
}
return 0;
}
棋盘问题:poj1321(DFS)
题意: 在n * n的棋盘的空白位置放入 m 个棋子,要求每个棋子的行列不相同;
思路: 数据量非常小,n < 8;
所以用结构体存一下空白位置的坐标,然后进行搜索就行了;
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 10 + 10;
char s[maxn][maxn];
struct Node
{
int x,y;
}a[maxn * maxn];
bool visx[maxn];
bool visy[maxn];
int n,m;
int ans;
int len;
void dfs(int length,int k)
{
if(length == m)
{
ans ++;
return;
}
for(int i = k; i < len ; i ++)
{
if(!visx[a[i].x] && !visy[a[i].y])
{
visx[a[i].x] = visy[a[i].y] = true;
dfs(length + 1,i);
visx[a[i].x] = visy[a[i].y] = false;
}
}
}
int main()
{
while( ~ scanf("%d%d",&n,&m) && !(n == -1 && m == -1))
{
ans = 0;
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
len = 0;
for(int i = 0; i < n ; i ++)
{
scanf("%s",s[i]);
for(int j = 0; j < n; j ++)
{
if(s[i][j] == '#')
{
a[len].x = i;
a[len ++].y = j;
}
}
}
if(len < m)
{
cout << 0 << endl;
continue;
}
// cout << len << " " << m << endl;
dfs(0,0);
cout << ans << endl;
}
return 0;
}
Find The Multiple dfs
题意: 找到能整除n 的的十进制数m, 并且m 数位上的数只由0,1组成;
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<map>
using namespace std;
typedef unsigned long long ll;
const ll maxn = 100 + 10;
#define INF 0x3f3f3f3f
bool flag;
void dfs(ll m,ll n,ll k)
{
if(flag)
return;
if(m % n == 0)
{
flag = true;
cout << m <<endl;
return;
}
if(k == 19)
{
return;
}
dfs(m * 10,n,k + 1);
dfs(m * 10 + 1,n,k + 1);
}
int main()
{
int n;
while( ~ scanf("%d",&n) && n)
{
flag = false;
dfs(1,n,0);
}
}
题意:
给定长度都为C两个字符串,S1,S2,和一个要求的结果字符串S12。先把 S2 的最下面一张牌放在最下面,然后S1,S2交错的叠放,得到新的S12,再把S12最下面的C个字符赋值给S1,把剩下的赋值给S2,再次重复上面的过程。最后求出要得到目标字符串S,问最少需要几步。
注意:
题目所给出的输入是从低向上排列的。
解析:
简单的bfs问题,直接模拟就好了。
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const ll maxn = 10000 + 10;
#define INF 0x3f3f3f3f
map<string,int>vis,tt;
int bfs(string s1,string s2,string s12)
{
queue<string>q;
string ss;
int len = s1.length();
for(int i = 0; i < len; i ++)
{
ss += s2[i];
ss += s1[i];
}
vis[ss] = 1;
tt[ss] = 1;
q.push(ss);
while(!q.empty())
{
string t = q.front();
q.pop();
if(t == s12)
{
return tt[t];
}
string ss1 ,ss2 ,ss3;
for(int i = 0; i < len; i ++)
ss1 += t[i];
for(int i = len; i < len * 2; i ++)
ss2 += t[i];
for(int i = 0; i < len; i ++)
{
ss3 += ss2[i];
ss3 += ss1[i];
}
if(!vis[ss3])
{
tt[ss3] = tt[t] + 1;
q.push(ss3);
if(ss3 == s12)
{
return tt[ss3];
}
}
}
return -1;
}
int main()
{
int Tcase;
scanf("%d",&Tcase);
for(int ii = 1; ii <= Tcase; ii ++)
{
vis.clear();
tt.clear();
int n;
scanf("%d",&n);
string s1,s2,s12;
cin >> s1 >> s2 >> s12;
int ans = bfs(s1,s2,s12);
cout << ii << " " << ans << endl;
}
return 0;
}