• 牛客刷题之数学基础-约数


    比赛地址

    牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)

    目录

    1.反素数 Antiprime

    2.Hankson 的趣味题

    3.最大公约数

    4.X-factor Chain

    5.聪明的燕姿

    6.Super GCD


     

    1.反素数 Antiprime

    题意:找一个最小的数且约数最多的数

    因为2e9+10中,一个数的约数最多有1600,所以可以暴力枚举

    然后用质数枚举即可

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. int primes[9]={2,3,5,7,11,13,17,19,23};
    5. int number,maxd;
    6. int n;
    7. void dfs(int u,int last,int p,int s)//u是当前第几个质数,last是质数的几次方,p是当前的数,s是约数个数
    8. {
    9. if(s>maxd||s==maxd&&p
    10. {
    11. maxd=s;
    12. number=p;
    13. }
    14. for(int i=1;i<=last;i++)
    15. {
    16. if((ll)p*primes[u]>n) break;
    17. p*=primes[u];
    18. dfs(u+1,i,p,s*(i+1));
    19. }
    20. }
    21. int main()
    22. {
    23. cin>>n;
    24. dfs(0,30,1,1);
    25. cout<
    26. return 0;
    27. }

    2.Hankson 的趣味题

    题意:

    • x和a0a_0a0​的最大公约数是a1a_1a1​;
    • x和b0b_0b0​的最小公倍数是b1b_1b1​。,求x的个数
    • 因为b1是x跟b0的最小公倍数,则直接枚举b1的所有约数即可,然后判断符不符合条件

    枚举一个数的约数,可以用暴搜即可,因为一个数的约数最多只有1600个,先处理出来所有质数的s次方在求约数即可 

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int N=1e5+10;
    5. int primes[N],cnt;
    6. bool st[N];
    7. int devide[1601],dcnt;
    8. int fcnt;
    9. struct Node
    10. {
    11. int p,s;
    12. }f[1601];//存一个质数p的s次方
    13. void init(int n)
    14. {
    15. for(int i=2;i<=n;i++)
    16. {
    17. if(!st[i]) primes[cnt++]=i;
    18. for(int j=0;primes[j]*i<=n;j++)
    19. {
    20. st[primes[j]*i]=true;
    21. if(i%primes[j]==0) break;
    22. }
    23. }
    24. }
    25. int gcd(int a,int b)
    26. {
    27. return b?gcd(b,a%b):a;
    28. }
    29. void dfs(int u,int p)//u是当前的质数,p是当前的数
    30. {
    31. if(u==fcnt)
    32. {
    33. devide[dcnt++]=p;
    34. return;
    35. }
    36. for(int i=0;i<=f[u].s;i++)
    37. {
    38. dfs(u+1,p);
    39. p*=f[u].p;
    40. }
    41. }
    42. void solve()
    43. {
    44. fcnt=dcnt=0;
    45. int res=0;
    46. int a0,a1,b0,b1;
    47. scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
    48. int m=b1;
    49. for(int i=0;primes[i]<=m/primes[i];i++)//将b1进行分解质因数
    50. {
    51. int p=primes[i];
    52. if(m%p==0)
    53. {
    54. int s=0;
    55. while(m%p==0) s++,m/=p;
    56. f[fcnt++]={p,s};
    57. }
    58. }
    59. if(m>1) f[fcnt++]={m,1};
    60. dfs(0,1);//暴力搜索所有的约数
    61. for(int i=0;i//枚举所有的约数看是否符合条件
    62. {
    63. int x=devide[i];
    64. if(gcd(x,a0)==a1&&(ll)x*b0/gcd(x,b0)==b1) res++;
    65. }
    66. printf("%d\n",res);
    67. }
    68. int main()
    69. {
    70. init(100000);
    71. int T;
    72. scanf("%d",&T);
    73. while(T--) solve();
    74. return 0;
    75. }

    3.最大公约数

    题意就是求一个超大数的最大公约数

    求最大公约数用减法来做,即a=a-b,b=a 这样子,然后的用高精度减法,并且存的数是ll的数

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. ll base=1e15,width=15;
    5. bool cmp(vector a,vector b)//比较哪个大
    6. {
    7. if(a.size()size()) return true;
    8. if(a.size()>b.size()) return false;
    9. for(int i=a.size()-1;i>=0;i--)
    10. if(a[i]return true;
    11. else if(a[i]>b[i]) return false;
    12. return false;
    13. }
    14. vector sub(vector a,vector b)//高精度减法
    15. {
    16. vector c;
    17. for(ll i=0;i<(ll)a.size();i++)
    18. {
    19. if(i>=(ll)b.size())
    20. {
    21. if(a[i]<0) a[i]+=base,a[i+1]--;
    22. c.push_back(a[i]);
    23. }
    24. else
    25. {
    26. if(a[i]1]--;
    27. c.push_back(a[i]-b[i]);
    28. }
    29. }
    30. while(c.back()==0&&c.size()>1) c.pop_back();
    31. return c;
    32. }
    33. void input(vector &a)
    34. {
    35. a.clear();
    36. string s;
    37. cin>>s;
    38. reverse(s.begin(),s.end());
    39. for(ll i=0;i<(ll)s.size();i+=width)
    40. {
    41. ll t=0;
    42. for(ll j=min(i+width,(ll)s.size())-1;j>=i;j--)
    43. t=t*10+(s[j]-'0');
    44. a.push_back(t);
    45. }
    46. }
    47. void output(vector a)
    48. {
    49. for(ll i=a.size()-1;i>=0;i--)
    50. if(i==(ll)a.size()-1) printf("%lld",a[i]);
    51. else printf("%015lld",a[i]);
    52. }
    53. vector gcd(vector a,vector b)
    54. {
    55. ll t=0;
    56. vector c;
    57. c.push_back(1);
    58. while(!cmp(b,c))//假如最小的不是1,则继续减
    59. {
    60. if(cmp(a,b)) swap(a,b);//一直让a是最大的
    61. if(cmp(b,c)) break;
    62. a=sub(a,b);//a=a-b
    63. }
    64. return a;
    65. }
    66. int main()
    67. {
    68. vector a,b;
    69. input(a),input(b);
    70. output(gcd(a,b));
    71. return 0;
    72. }

    python做法直接秒

    1. import math as ma
    2. a = int(input())
    3. b = int(input())
    4. print(ma.gcd(a, b))

    4.X-factor Chain

    X-factor Chain--质因数分解+组合数学_小元勋的博客-CSDN博客

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int N=1e5+10;
    5. int primes[N],cnt;
    6. bool st[N];
    7. int devide[1601],dcnt;
    8. int fcnt=0;
    9. struct
    10. {
    11. int p,s;
    12. }f[1601];
    13. void init(int n)
    14. {
    15. for(int i=2;i<=n;i++)
    16. {
    17. if(!st[i]) primes[cnt++]=i;
    18. for(int j=0;primes[j]*i<=n;j++)
    19. {
    20. st[primes[j]*i]=true;
    21. if(i%primes[j]==0) break;
    22. }
    23. }
    24. }
    25. ll get(int n)
    26. {
    27. ll res=1;
    28. for(int i=1;i<=n;i++) res=(ll)res*i;
    29. return res;
    30. }
    31. int main()
    32. {
    33. init(N-1);
    34. int x;
    35. while(cin>>x)
    36. {
    37. dcnt=fcnt=0;
    38. for(int i=0;primes[i]<=x/primes[i];i++)
    39. {
    40. int p=primes[i];
    41. if(x%p==0)
    42. {
    43. int s=0;
    44. while(x%p==0) s++,x/=p;
    45. f[fcnt++]={p,s};
    46. }
    47. }
    48. if(x>1) f[fcnt++]={x,1};
    49. sort(devide,devide+dcnt);
    50. ll len=0,k=1;
    51. for(int i=0;i
    52. {
    53. len+=f[i].s;
    54. k*=get(f[i].s);
    55. }
    56. k=get(len)/k;
    57. cout<' '<
    58. }
    59. return 0;
    60. }

    5.聪明的燕姿

    AcWing 1296. 聪明的燕姿 - AcWing

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int N=5e4+10;
    5. int primes[N],cnt;
    6. bool st[N];
    7. int S;
    8. int ans[N],acnt;
    9. void init(int n)
    10. {
    11. for(int i=2;i<=n;i++)
    12. {
    13. if(!st[i]) primes[cnt++]=i;
    14. for(int j=0;primes[j]*i<=n;j++)
    15. {
    16. st[primes[j]*i]=true;
    17. if(i%primes[j]==0) break;
    18. }
    19. }
    20. }
    21. bool judge(int n)
    22. {
    23. if(nreturn !st[n];
    24. for(int i=0;primes[i]<=n/primes[i];i++)
    25. if(n%primes[i]==0) return false;
    26. return true;
    27. }
    28. void dfs(int u,int p,int last)
    29. {
    30. if(last==1)
    31. {
    32. ans[acnt++]=p;
    33. return;
    34. }
    35. if(last-1>primes[u>0?u:0]&&judge(last-1))
    36. {
    37. ans[acnt++]=p*(last-1);
    38. }
    39. for(int i=u+1;primes[i]<=last/primes[i];i++)
    40. {
    41. int pm=primes[i];
    42. for(int j=pm+1,t=pm;j<=last;t*=pm,j+=t)
    43. if(last%j==0)
    44. dfs(i,p*t,last/j);
    45. }
    46. }
    47. int main()
    48. {
    49. init(N-1);
    50. while(scanf("%d",&S)!=EOF)
    51. {
    52. acnt=0;
    53. dfs(-1,1,S);
    54. printf("%d\n",acnt);
    55. sort(ans,ans+acnt);
    56. if(acnt>=1)
    57. {
    58. for(int i=0;iprintf("%d ",ans[i]);
    59. puts("");
    60. }
    61. }
    62. return 0;
    63. }

    6.Super GCD

    这题跟第三题差不多,只不过数据开大了,可以直接看第三天的题解

  • 相关阅读:
    egg-token码的生成与验证
    Redis和MySQL如何保持数据一致性
    Vite2.0+Vue3.0+Element-Plus+TypeScript 项目配置及初始化
    算法---不同路径(Kotlin)
    全局平均池化 - 从特征图到全局信息
    电机与拖动 - 7 直流电机
    Java基础之浅聊 CompletableFuture类
    ZYNQ从vitis生成linux系统编译启动文件
    Spring IOC的应用
    网课查题公众号快速搭建法 内含接口及新手教程
  • 原文地址:https://blog.csdn.net/m0_63729880/article/details/127434472