• 1072: [SCOI2007]排列perm


    Description

    给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种。
    Input

    输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开。s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
    Output

    每个数据仅一行,表示能被d整除的排列的个数。
    Sample Input
    7
    000 1
    001 1
    1234567890 1
    123434 2
    1234 7
    12345 17
    12345678 29

    Sample Output
    1
    3
    3628800
    90
    3
    6
    1398

    HINT

    在前三个例子中,排列分别有1, 3, 3628800种,它们都是1的倍数。 【限制】 20%的数据满足:s的长度不超过5, 1<=T<=5 50%的数据满足:s的长度不超过8 100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15,

    状压dp

    f[s,i]表示状态为s(用二进制表示选的数字的情况),余数为i的方案数

    最后把重复的去掉,即除以每一种数字的个数的阶乘

     1 var
     2         flag,f:array[0..1024,0..1000]of longint;
     3         x,y:array[0..1000000]of longint;
     4         t,time,d,n:longint;
     5         s:array[0..10]of longint;
     6 
     7 procedure init;
     8 var
     9         c:char;
    10 begin
    11         read(c);
    12         n:=0;
    13         while c<>' ' do
    14           begin
    15             inc(n);
    16             s[n]:=ord(c)-ord('0');
    17             read(c);
    18           end;
    19         readln(d);
    20 end;
    21 
    22 procedure work;
    23 var
    24         head,tail,i,j,k,nx,ny:longint;
    25 begin
    26         flag[0,0]:=time;
    27         f[0,0]:=1;
    28         head:=1;
    29         tail:=1;
    30         x[1]:=0;
    31         y[1]:=0;
    32         while head<=tail do
    33           begin
    34             for i:=1 to n do
    35               if x[head] and (1<<(i-1))=0 then
    36               begin
    37                 nx:=x[head]+1<<(i-1);
    38                 ny:=(y[head]*10+s[i])mod d;
    39                 if flag[nx,ny]<>time then
    40                 begin
    41                   flag[nx,ny]:=time;
    42                   f[nx,ny]:=0;
    43                   inc(tail);
    44                   x[tail]:=nx;
    45                   y[tail]:=ny;
    46                 end;
    47                 inc(f[nx,ny],f[x[head],y[head]]);
    48               end;
    49             inc(head);
    50           end;
    51         for i:=1 to n do
    52           begin
    53             k:=0;
    54             for j:=1 to i do
    55               if s[j]=s[i] then inc(k);
    56             f[1<<n-1,0]:=f[1<<n-1,0] div k;
    57           end;
    58         if flag[1<<n-1,0]=time then writeln(f[1<<n-1,0])
    59         else writeln(0); 
    60 end;
    61 
    62 begin
    63         readln(t);
    64         while t>0 do
    65           begin
    66             dec(t);
    67             inc(time);
    68             init;
    69             work;
    70           end;
    71 end.
    View Code
  • 相关阅读:
    Java并发2
    使用Redis锁可能出现的问题
    社区项目前端vue总结
    社区项目Redis分布式锁穿透击穿雪崩
    社区项目遇到的问题
    html2canvas 下载的图片有空白 Amy
    html2canvas 支持backgroundClip:text Amy
    查看nacvicate连接数据库密码
    CPU飙升问题排查
    vue3 学习笔记
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3684693.html
Copyright © 2020-2023  润新知