您的位置:首页 > 其它

搜索入门

2015-06-13 10:40 330 查看
记录点滴。

/*
2015.6    HT
ACM Work_9

*/

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

/*
Can you find it

Ai+Bj+Ck = X
*/
//int a[505], b[505], c[505];
//int sum[505 * 505];
//int l, n, m, k;
//int flag;
//
//// 二分查找
//void binary(int x)
//{
//    int left, right, mid;
//    left = 0;
//    right = k - 1;
//    while (left <= right)
//    {
//        mid = (left + right) / 2;
//        if (sum[mid] > x)
//            right = mid - 1;
//        else if (sum[mid]<x)
//            left = mid + 1;
//        else
//        {
//            flag = 1;
//            return;
//        }
//    }
//    return;
//}
//
//int main()
//{
//    int i, j, q, x, count = 1;
//    while (cin >> l >> n >> m)
//    {
//        for (i = 0; i<l; i++)
//            cin >> a[i];
//        for (i = 0; i<n; i++)
//            cin >> b[i];
//        for (i = 0; i<m; i++)
//            cin >> c[i];
//
//        k = 0;
//        for (i = 0; i<l; i++)
//        for (j = 0; j<n; j++)
//        {
//            sum[k++] = a[i] + b[j];
//        }
//        sort(sum, sum + k);
//
//        cin >> q;
//        cout << "Case " << count++ << ":" << endl;
//
//        while (q--)
//        {
//            cin >> x;
//            flag = 0;
//            for (i = 0; i<m; i++)
//            {
//                binary(x - c[i]);
//                if (flag)
//                {
//                    cout << "YES" << endl;
//                    break;
//                }
//            }
//            if (!flag)
//                cout << "NO" << endl;
//        }
//    }
//    return 0;
//}

/*
Strange fuction

F(x) = 6*x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)
求其给定范围内的最小值
一阶导F'(x) = 42*x^6+48*x^5+21*x^2+10*x-y
无论y取什么值,总可以找到x1∈[0, 100]使F'(x1)=0,x∈[0, x1]时,函数递减
x∈[x1, 100]时,函数递增。所以F(x1)便是极小值,也是最小值
*/
//const double eps = 1e-6;
//int t;
//double y;
//double fun(double x)
//{
//    return 6 * pow(x, 7) + 8 * pow(x, 6) + 7 * pow(x, 3) + 5 * pow(x, 2) - y*x;
//}
//
//double func(double x)
//{
//    return 42 * pow(x, 6) + 48 * pow(x, 5) + 21 * pow(x, 2) + 10 * x - y;
//}
//
//int main()
//{
//    scanf_s("%d", &t);
//    while (t--)
//    {
//        scanf_s("%lf", &y);
//        double ll = 0, rr = 1e2, mid;
//        while (ll + eps <= rr)
//        {
//            mid = (ll + rr) / 2;
//            if (func(mid)>0)
//                rr = mid;
//            else
//                ll = mid;
//        }
//        printf_s("%.4f\n", fun(mid));
//    }
//    return 0;
//}

/*
Tempter of the Bone:

奇偶性剪枝:
可以把map看成这样:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从为 0 的格子走一步,必然走向为 1 的格子
从为 1 的格子走一步,必然走向为 0 的格子
即:
0 ->1或1->0 必然是奇数步
0->0 走1->1 必然是偶数步

结论:
所以当遇到从 0 走向 0 但是要求时间是奇数的,或者从 1 走向 0 但是要求时间是偶数的 都可以直接判断不可达!

X: 墙壁
S: 开始位置
D: 迷宫的门
.: 空的方格

*/
char map[101][101];
int n, m, fx, fy;
bool isok;

void dfs(int x, int y, int time)
{
if (isok == 1)
return;

// 是否越界
if (x<0 || y<0 || x > n - 1 || y > m - 1 || time<0 || map[x][y] == 'X')
return;

// 减枝  最短步数减枝  奇偶减枝
if (time < abs(fx - x) + abs(fy - y) || (time - (abs(fx - x) + abs(fy - y))) % 2)
return;

// 是否到了终点
else if (time == 0 && (fx == x && fy == y))
{
isok = true;
return;
}

// 四个方向遍历
else
{
map[x][y] = 'X';
dfs(x - 1, y, time - 1);
map[x][y] = '.';

map[x][y] = 'X';
dfs(x + 1, y, time - 1);
map[x][y] = '.';

map[x][y] = 'X';
dfs(x, y - 1, time - 1);
map[x][y] = '.';

map[x][y] = 'X';
dfs(x, y + 1, time - 1);
map[x][y] = '.';
}
return;

}

int main()
{
int i, j, sx, sy, t;

while (cin >> n >> m >> t)
{
if (n == 0 && m == 0 && t == 0)
break;

for (i = 0; i<n; ++i)
for (j = 0; j<m; ++j)
{
cin >> map[i][j];
if (map[i][j] == 'S')
{
sx = i;
sy = j;
}
else if (map[i][j] == 'D')
{
fx = i;
fy = j;
}
}

isok = false;
dfs(sx, sy, t);
if (isok == 1)
cout << "YES" << endl;
else
cout << "NO" << endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: