zoukankan      html  css  js  c++  java
  • bzoj3733 [Pa2013]Iloczyn

    Description

    给定正整数n和k,问能否将n分解为k个不同正整数的乘积

    Input

    第一行一个数T(T<=4000)表示测试组数
    接下来T行每行两个数n(n<=10^9),k(k<=20)

    Output

    输出T行,若可以被分解,输出"TAK"否则输出"NIE"

    Sample Input

    3
    15 2
    24 4
    24 5

    Sample Output

    TAK
    TAK
    NIE
     
    正解:搜索。
    直接筛出所有约数,然后搜索就行了。
    有一个剪枝,就是如果现在可以选的最小的$k-now$的数与当前乘积的乘积大于$n$,就可以直接剪掉了。
     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 
     6 using namespace std;
     7 
     8 int sum[100010][22],fac[100010],n,k,tot;
     9 
    10 il int gi(){
    11   RG int x=0,q=1; RG char ch=getchar();
    12   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    13   if (ch=='-') q=-1,ch=getchar();
    14   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    15   return q*x;
    16 }
    17 
    18 il void factor(RG int n){
    19   tot=0;
    20   for (RG int i=2;i*i<=n;++i){
    21     if (n%i) continue; fac[++tot]=i;
    22     if (i*i!=n) fac[++tot]=n/i;
    23   }
    24   sort(fac+1,fac+tot+1); return;
    25 }
    26 
    27 il int dfs(RG int now,RG int rem,RG int pro){
    28   if (!rem) return n==pro;
    29   for (RG int i=now;i+rem<=tot+1;++i){
    30     if (sum[i][rem]==-1) return 0;
    31     if (1LL*pro*sum[i][rem]>n) return 0;
    32     if (dfs(i+1,rem-1,pro*fac[i])) return 1;
    33   }
    34   return 0;
    35 }
    36 
    37 il void work(){
    38   n=gi(),k=gi(); if (k==1){ puts("TAK"); return; }
    39   if (k==2){ puts(n!=1 ? "TAK" : "NIE"); return; } factor(n),--k;
    40   for (RG int i=1;i<=tot;++i){
    41     sum[i][0]=1;
    42     for (RG int j=1;j<=k;++j){
    43       if (sum[i][j-1]==-1 || 1LL*sum[i][j-1]*fac[i+j-1]>n) sum[i][j]=-1;
    44       else sum[i][j]=sum[i][j-1]*fac[i+j-1];
    45     }
    46   }
    47   puts(dfs(1,k,1) ? "TAK" : "NIE"); return;
    48 }
    49 
    50 int main(){
    51 #ifndef ONLINE_JUDGE
    52   freopen("Iloczyn.in","r",stdin);
    53   freopen("Iloczyn.out","w",stdout);
    54 #endif
    55   RG int T=gi();
    56   while (T--) work();
    57   return 0;
    58 }
  • 相关阅读:
    需求的陷阱
    VS2008 NumericUpDown控件 内容全选
    KeyPress 事件中 keycode对应的按键
    C#发送邮件
    Stream 和Byte[] 之间的转换
    SQL ISNULL() 函数
    修改struts2的.action后缀名
    #pragma data_seg
    VBA中Option的四种用法
    SetWindowsHookEx
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7668083.html
Copyright © 2011-2022 走看看