eg.1
原题链接:https://ac.nowcoder.com/acm/contest/9986/I
AC代码:
#include
using namespace std;
const int N = 1000;
struct node{
int x;
int y;
int step;
}s,g,Node;
int n,m,flag;
char mp[N][N];
int vis[N][N];
int X[5]={0, 0, 1, -1};
int Y[5]={1, -1, 0, 0};
bool judge(int x, int y){
if(x < 1 || x > n || y < 1 || y > m || mp[x][y] == '#' || vis[x][y] == 1) return 0;
else return 1;
}
void bfs(){
queue<node>q;
q.push(s);
while(q.empty() != 1){
node top = q.front();
q.pop();
if(top.x == g.x && top.y == g.y){
flag = 1;
cout << top.step * 100 << endl;
return;
}
for(int i = 0; i < 4; i++){
int newx = top.x + X[i];
int newy = top.y + Y[i];
if(judge(newx, newy)){
Node.x = newx, Node.y = newy;
Node.step = top.step+1;
q.push(Node);
vis[newx][newy] = 1;
}
}
}
if(flag == 0){
cout << "-1" << endl;
return;
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
while(cin >> n >> m){
cin >> s.x >> s.y >> g.x >> g.y;
flag = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> mp[i][j];
vis[i][j] = 0;
}
}
s.step = 0;
bfs();
}
return 0;
}
eg.2 hdu1072
AC代码:
#include
using namespace std;
int n, m, a, bx, by;
int mmap[10][10];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
struct node{
int x;
int y;
int step;
int time;
};
void bfs(){
queue<node> q;
node t = {bx, by, 0, 6};
q.push(t);
while(!q.empty()){
node p;
p = q.front();
q.pop();
for (int i = 0; i < 4; ++i){
t.x = dx[i] + p.x;
t.y = dy[i] + p.y;
t.step = p.step + 1;
t.time = p.time - 1;
if(t.x >= 0 && t.x < n && t.y >= 0 && t.y < m && t.time > 0 && mmap[t.x][t.y] != 0){//0为墙
if(mmap[t.x][t.y] == 3){//到达终点
cout << t.step << endl;
return ;
}
if(mmap[t.x][t.y] == 4){
t.time = 6;
mmap[t.x][t.y] = 0;
}
q.push(t);
}
}
}
cout << -1 << endl;
return ;
}
int main(){
cin >> a;
while(a--){
cin >> n >> m;
for (int i = 0; i < n; ++i){
for (int j = 0; j < m; ++j){
cin >> mmap[i][j];
if(mmap[i][j] == 2) {
bx = i;
by = j;
}
}
}
bfs();
}
return 0;
}
eg.1hdu1010
知识点 :
1.曼哈顿距离、欧氏距离
2.奇偶剪枝
exter是偶数就能走到终点。
3.dfs是用递归实现的。那么如果我们找到了终点并且路数也符合,不能只是让 指示变量(flag)变值那么简单,还要在每次递归返回后面再加上一个判断,目的是终止查找,如果不这样做,就算找到了结果是YES我们也必须等到整个图全部被扫描完才可以结束程序,这样就增加了时间复杂度。
#include //DFS
using namespace std;
typedef long long ll;
int n, m, t, step, xs, ys, xe, ye, num;//xs,ys起点。xe,ye终点
bool flag;
int dx[5] = {1, 0, 0, -1};//bfs和dfs都要写这一步
int dy[5] = {0, 1, -1, 0};
char mmap[8][8];
bool judge(int x, int y){//判断是否在地图里。bfs和dfs都要写
if(x >= 0 && x < n && y >= 0 && y < m) return 1;//可以=0
else return 0;
}
void dfs(int x, int y, int step){
if(step == t && x == xe && y == ye) {
flag = 1;
return ;
}
if((abs(x - xe) + abs(y - ye)) > t - step) return ;//剪枝,该点到终点的距离大于所给的最小距离。
if((abs(x - xe) + abs(y - ye)) % 2 != (t - step) % 2) return ;//奇偶剪枝
for (int i = 0; i < 4; ++i){
int dxx = x + dx[i];
int dyy = y + dy[i];
if(judge(dxx, dyy) && mmap[dxx][dyy] != 'X'){//X是不能走的地方
mmap[dxx][dyy] = 'X';//标记走过的地方为不可走的
dfs(dxx, dyy, step + 1);
mmap[dxx][dyy] = '.';//撤销上一步尝试。
}
}
}
int main(){
while(cin >> n >> m >> t){
if(n == 0 && m == 0 && t == 0) break;
num = 0;//最多可以走多少步
flag = 0;
for (int i = 0; i < n; ++i){//读入迷宫地图
for (int j = 0; j < m; ++j){
cin >> mmap[i][j];
if(mmap[i][j] == 'S'){//找到起点
xs = i;
ys = j;
}
else if(mmap[i][j] == 'D'){
xe = i;
ye = j;
num++;
}
else if (mmap[i][j] == '.'){
num++;
}
}
}
mmap[xs][ys] = 'X';//因为不能回头走,所以把起点标记成不能走的路
if(num >= t) dfs(xs, ys, 0);
if(flag == 1) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
eg.2 hdu1015
题意:
给定一个目标值target,再给你一个备选字符串(5~12个字符),要你在这个字符串里选5个出来,满足题中给定的等式,并且你选择的这5个字符组成的字符串必须是所有可能情况中按字典序最大的情况。
知识点:
1.打表:
意指对一些题目,通过打表技巧获得一个有序表或常量表,来执行程序某一部分,优化时间复杂度。这种算法也可用于在对某种题目没有最优解法时,用来得到分数的一种策略。
2.memset初始化字符数组。
#include
using namespace std;
int n;
char str[25];
int s[25], f[25], flag[25];
bool cmp(char a, char b){
return a > b;//降序排列
}
int res(int v, int w, int x, int y, int z){
return v - w*w + x*x*x - y*y*y*y + z*z*z*z*z;
}
int dfs(int n, int len, int step){
if(step == 5){
if(res(f[0], f[1], f[2], f[3], f[4]) == n) return 1;
else return 0;
}
for (int i = 0; i < len; ++i){
if(flag[i]) continue;
flag[i] = 1;
f[step] = s[i];
if(dfs(n, len, step + 1)) return 1;
flag[i] = 0;
}
return 0;
}
int main(){
memset(str, 'A', 20);
while(cin >> n >> str){
if(n == 0 && str[0] == 'E' && str[1] == 'N' && str[2] == 'D') break;
int len = strlen(str);
sort(str, str + len, cmp);//按字典序排序。因为题目要求按字典序从大到小。 sort默认升序,降序需要自己写函数
for (int i = 0; i < len; ++i){
flag[i] = 0;
s[i] = str[i] - 'A' + 1;//保证每个字母的值都在1~26之间
}
if(dfs(n, len, 0)){
for (int i = 0; i < 5; ++i){
printf("%c", f[i] + 'A' - 1);
}
cout << endl;
}
else cout << "no solution" << endl;
}
return 0;
}