• POJ3708 Recurrent Function


    【题意】

      给出一个正整数d(2<=d<=100);一个元素个数为d-1的集合a,每个集合元素ai对应一个1~d-1的整数;以及定义相同的大小为d集合bi。

      f函数的定义原题已给出。求数m最少经过多少次函数操作变为数k,无解输出NO。

    【题解】

      我们可发现当x>=d时,f(x)=d*f(x/d)+b[x mod d],x<d时,f(x)=a[x]。

      不难发现其实这就是在x的d进制下,对每一位进行变换,某一位如果是x,要么变a[x],要么变b[x]。所以答案就是当某一次操作后,每一位都与目标数一致。

      于是对m在d进制下的每一位找第一次到达目标数的次数以及循环节(之所以有a与b两个集合就是防止最高位变为0)。最后就成了求n个模线性方程组求解的问题。

    【代码】

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #define ll long long
      6 using namespace std;
      7 struct node
      8 {
      9     ll a,r;
     10 }a[1000];
     11 int n,A[105],B[105],flag[105],po[1000],sum[1000],c[1000],d[1000];
     12 ll D;
     13 char st[105];
     14 int read()
     15 {
     16     int x=0,sign=1;char ch;
     17     do{ch=getchar();if(ch=='-')sign=-sign;}while(ch<'0'||ch>'9');
     18     do{x=x*10+ch-48;ch=getchar();}while(ch>='0'&&ch<='9');
     19     return x*sign;
     20 }
     21 void exgcd (ll a,ll b,ll &x,ll &y)
     22 {
     23     if (b==0)
     24     {
     25         D=a;
     26         x=1;
     27         y=0;
     28         return;
     29     }
     30     exgcd(b,a%b,x,y);
     31     ll t=x;
     32     x=y;
     33     y=t-a/b*y;
     34 }
     35 ll crt(node a[],int n)
     36 {
     37     for (int i=1;i<=n;++i)    if (a[i].r==-1) return -1;
     38     ll A=a[1].a,R=a[1].r,x,y,q;
     39     for (int i=2;i<=n;++i)
     40     {
     41         exgcd(A,-a[i].a,x,y);
     42         if ((a[i].r-R)%D)return -1;
     43         q=-a[i].a/D;
     44         x=(a[i].r-R)/D%q*x%q;
     45         R=A*x+R;        
     46         A=q*A;
     47     }
     48     if (A<0) A=-A;    
     49     return (R%A+A)%A;
     50 }
     51 node rpt(int A[],int n,int x,int y)
     52 {
     53     int cnt=0;
     54     for (int i=0;i<=n;++i)    flag[i]=0;
     55     while (!flag[x])
     56         flag[x]=++cnt,x=A[x];    
     57     return {cnt,flag[y]-1};
     58 }
     59 void div(int sum[],int d)
     60 {
     61     po[0]=0;int x=0;
     62     for (int i=1;i<=sum[0];++i)
     63     {
     64         x=x*10+sum[i];
     65         if (!po[0] && x>=d || po[0])
     66             po[++po[0]]=x/d,x%=d;            
     67     }
     68     sum[0]=po[0];
     69     for (int i=1;i<=po[0];++i)    sum[i]=po[i];
     70 }
     71 int mo(int sum[],int d)
     72 {
     73     int x=0;
     74     for (int i=1;i<=sum[0];++i)
     75     {
     76         x=x*10+sum[i];
     77         if (x>=d)    x=x%d;
     78     }
     79     return x;
     80 }
     81 void get(int c[],int d)
     82 {
     83     scanf("%s",st+1);
     84     sum[0]=strlen(st+1);
     85     for (int i=1;i<=sum[0];++i)
     86         sum[i]=st[i]-48;
     87     c[0]=0;
     88     while (sum[0])
     89     {
     90         c[++c[0]]=mo(sum,d);
     91         div(sum,d);
     92     }
     93     for (int i=1;i+i<=c[0];++i)        swap(c[i],c[c[0]-i+1]);
     94 }
     95 int main()
     96 {
     97     while (1)
     98     {
     99         n=read();
    100         if (n==-1)    break;
    101         for (int i=1;i<n;++i)    A[i]=read();
    102         for (int i=0;i<n;++i)    B[i]=read();
    103         get(c,n);get(d,n);
    104         if (c[0]!=d[0]){puts("NO");continue;}    
    105         a[1]=rpt(A,n-1,c[1],d[1]);
    106         for (int i=2;i<=c[0];++i)    a[i]=rpt(B,n,c[i],d[i]);
    107         ll ans=crt(a,c[0]);
    108         if (ans==-1)    puts("NO");
    109         else printf("%I64d\n",ans);
    110     }
    111     return 0;
    112 }
    View Code

      说实话写的有点丑。。。。

  • 相关阅读:
    Delphi XE4 FireMonkey 开发 IOS APP 发布到 AppStore 最后一步.
    Native iOS Control Delphi XE4
    Delphi XE4 iAD Framework 支持.
    using IOS API with Delphi XE4
    GoF23种设计模式之行为型模式之命令模式
    Android青翼蝠王之ContentProvider
    Android白眉鹰王之BroadcastReceiver
    Android倚天剑之Notification之亮剑IOS
    Android紫衫龙王之Activity
    GoF23种设计模式之行为型模式之访问者模式
  • 原文地址:https://www.cnblogs.com/Bleacher/p/6869339.html
Copyright © 2020-2023  润新知