Hdu 4474 Yet Another Multiple Problem

来源:互联网 发布:淘宝大学免费课程下载 编辑:程序博客网 时间:2024/05/29 19:34

原题网址:http://acm.hdu.edu.cn/showproblem.php?pid=4474
这里写图片描述
按照数的位数BFS,从小向大枚举就可以保证构造出来的数是递增的,如果不加判断就直接搜索的话,复杂度非常高。因此需要剪枝。
优化方法:如果一个数%N==0,那么这个数就是N的倍数。在没有找到的前提下,如果A%N==B%N,而且A < B,那么其实我们就可以取A而不取B,因为如果在A末尾增加C可以使得AC%N==0,那么BC%N也等于0,易得:如果A和B追加数之后%N==0,那么最优条件下追加的数肯定相同。
因此我们只需要维护组合出来的数%N的值即可,如果在搜索的途中出现了相同的%N值,就可以直接忽略了,因为肯定没有前面的优秀。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 1000020struct node {    int pre, mod;    char c;} q[N];int n, m;bool v[10010];void print(int x) {    if (x == 0) return ;    print(q[x].pre);    putchar(q[x].c);}int main() {    int cas = 1, t, a[10];    bool vis[10];    while (scanf("%d%d", &n, &m) == 2) {        memset(vis, false, sizeof(vis));        for (int i=0; i<m; i++) {            scanf("%d", &t); vis[t] = true;        }        m = 0;        for (int i=0; i<10; i++) if (!vis[i]) a[m++] = i;        printf("Case %d: ", cas++);        if (m == 0) {            puts("-1"); continue;        }        memset(v, false, sizeof(v));        int l = 1, r = 1, ans = -1;        for (int i=0; i<m; i++) if (a[i]) {            q[r].pre = 0;            v[q[r].mod = a[i] % n] = true;            q[r].c = a[i] + '0';            if (q[r].mod == 0) { ans = r; break; }            r++;        }        while (l < r && ans == -1) {            for (int i=0; i<m; i++) {                q[r].mod = (q[l].mod*10 + a[i])%n;                if (!v[q[r].mod]) {                    v[q[r].mod] = true;                    q[r].pre = l;                    q[r].c = a[i] + '0';                    if (q[r].mod == 0) { ans = r; break; }                    r++;                }            }            l++;        }        if (ans == -1) puts("-1");        else {            print(ans); printf("\n");        }    }    return 0;}
var  q,last,dig:array[0..20000] of int64;  vis:array[0..10000] of boolean;  use:array[0..9] of boolean;  a:array[0..100] of int64;  cnt,n,m,i,head,tail:longint;  now:int64;  finished:boolean;procedure print(x:longint);  begin    if (x=0)       then write('Case ',cnt,': ')      else begin print(last[x]);write(dig[x]);end;  end;begin  cnt:=0;  while not eof do    begin      read(n,m);inc(cnt);      if n=0 then break;      fillchar(use,sizeof(use),true);      for i:=1 to m do        begin          read(a[i]);          use[a[i]]:=false;        end;      a[0]:=0;      for i:=0 to 9 do        if use[i] then          begin            inc(a[0]);            a[a[0]]:=i;          end;      fillchar(vis,sizeof(vis),false);      head:=1;tail:=1;finished:=false;      for i:=1 to a[0] do        if (a[i]<>0)and(not vis[a[i] mod n]) then          begin            q[tail]:=a[i] mod n;dig[tail]:=a[i];last[tail]:=0;inc(tail);            vis[a[i] mod n]:=true;            if (a[i] mod n=0) then              begin                finished:=true;                print(tail-1);writeln;                break;              end;          end;      if finished then continue;      while head<tail do        begin          for i:=1 to a[0] do            begin              now:=(q[head]*10+a[i]) mod n;              if not vis[now] then                begin                  q[tail]:=now;dig[tail]:=a[i];last[tail]:=head;inc(tail);                  vis[now]:=true;                  if now=0 then                    begin                      finished:=true;                      print(tail-1);writeln;                      break;                    end;                end;            end;          inc(head);          if (finished) then break;        end;      if (not finished)or(now>maxlongint)        then writeln('Case ',cnt,': -1');    end;end.

原题解网址:http://blog.csdn.net/yang_7_46/article/details/12356587

0 0
原创粉丝点击