HDU4474(搜索思想)

来源:互联网 发布:spss时间序列数据预测 编辑:程序博客网 时间:2024/05/17 12:23

    先贴一发,还不是太理解

    /** * 比较巧的广搜+记录最短路径 * 搜余数,骚的一匹。。。 * 用余数做结点,复杂度10000 * 复习题 * n1 mod k = (n1 mod k) mod k * (n1 + n2) mod k = ((n1 mod k) + (n2 mod k)) mod k * (n1 * w) mod k = ((n1 mod k) * w) mod k * 已保证先搜到的是最小的。 */#include<iostream>#include<cstdio>#include<queue>#include<algorithm>#include<cstring>using namespace std;const int mmax = 10002;bool book[mmax];bool unincluded[11];int n;char route[mmax];//字符串输出,每个下标(余数)只存一位数,也可以用intint pre[mmax];bool bfs(){    queue<int> Q;    Q.push(0);//先放一个数,为何放0    int now;//代表余数,其实本来是要代表的未取余的数,但经过证明可以用余数代替。    while(!Q.empty())    {        now = Q.front();        Q.pop();        for(int i = 0; i < 10; i++)//必须从0开始,遍历数字0-9        {            if(unincluded[i])//不允许使用的数字                continue;            if(now == 0 && i == 0)//排除第一个??                continue;            int next = (now * 10 + i)%n;//下一个余数            if(book[next])//如果余数用过,则不加入,剪枝                continue;            route[next] = '0' + i;            book[next] = true;            pre[next] = now;//记录到达这个余数前面的余数            Q.push(next);            if(next == 0)//可以放到开头            {                return true;            }        }    }    return false;}void out(){    int p = 0;    string output;    while(p != 0 || output.empty())    {        output += route[p];        p = pre[p];    }    reverse(output.begin(), output.end());    puts(output.c_str());//c语言遗留的,书上写的,返回指针}int t;int main(){    int m;    t = 1;    while(scanf("%d%d", &n, &m) != EOF)    {        memset(unincluded, 0, sizeof(unincluded));        memset(book, 0, sizeof(book));        int num;        for(int i = 1; i <= m; i++)        {            scanf("%d", &num);            unincluded[num] = true;        }        printf("Case %d: ", t);        if(bfs())        {            out();        }        else        {            printf("-1\n");        }        t++;    }    return 0;}