BZOJ3733 : [Pa2013]Iloczyn

首先将$n$的约数从小到大排序,设$dfs(x,y,z)$表示当前可以选第$x$个到第$m$个约数,还要选$y$个,之前选的乘积为$z$是否可能。

爆搜的时候,如果从$x$开始最小的$y$个相乘也超过了$n$,那么就不合法,加上这个剪枝即可。

#include<cstdio>
#include<algorithm>
#define N 2000
int T,n,k,m,i,j,q[N],f[N][22];
int dfs(int x,int y,int z){
  if(!y)return z==n;
  for(y--;x+y<=m;x++){
    if(f[x][y]<0)return 0;
    if(1LL*f[x][y]*z>n)return 0;
    if(dfs(x+1,y,z*q[x]))return 1;
  }
  return 0;
}
int main(){
  scanf("%d",&T);
  while(T--){
    scanf("%d%d",&n,&k);
    for(m=0,i=1;i*i<=n;i++)if(n%i==0){
      q[++m]=i;
      if(i*i!=n)q[++m]=n/i;
    }
    std::sort(q+1,q+m+1);
    for(i=1;i<=m;i++){
      long long t=1;
      for(j=0;j<k&&i+j<=m;f[i][j++]=t)if(t>0){
        t*=q[i+j];
        if(t>n)t=-1;
      }
    }
    puts(dfs(1,k,1)?"TAK":"NIE");
  }
  return 0;
}

  

时间: 2024-08-01 22:43:09

BZOJ3733 : [Pa2013]Iloczyn的相关文章

【PA2013】【BZOJ3733】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 HINT Source 如今BZOJ上不去没有中文题面也没法在BZO

[Pa2013]Iloczyn

https://www.zybuluo.com/ysner/note/1300802 题面 给定正整数\(n\)和\(k\),问能否将\(n\)分解为\(k\)个不同正整数的乘积. \(n\leq10^9,k\leq20,T\leq4000\) 解析 这破题目卡常,删了一堆define快一倍 可以发现\(12!=479001600>10^9\). 所以\(n\)顶多被分解成\(11\)个不同正整数. 常规操作:找出所有约数然后\(O(2^{11})\)枚举加剪枝. 然而我不会搜索啊,\(TLE\

省选之前的未完成的计划(截至到省选)

PLAN OF THE COMING HEOI good problems:-bzoj4823:[Cqoi2017]老C的方块 [*]-bzoj3171:[Tjoi2013]循环格 [*]-bzoj4200:[Noi2015]小园丁与老司机 [*]-bzoj1061:[Noi2008]志愿者招募 [*]-bzoj3600:没有人的算术 [*]-bzoj2806:[Ctsc2012]Cheat [*]-bzoj2219:数论之神 [*]-bzoj2595:[Wc2008]游览计划 [*]-bzoj

波兰题目补全计划

Introduce 本人比较喜欢做波兰的题目,感觉这些题目十分清真,思维也比较好.欢迎同样喜欢波兰题目的OIer来交流.以下是我有记录地刷过的题目. 比较好的题吧:BZOJ #3746.[POI2015]Czarnoksi??nicy okr?g?ego sto?u source:XXII OI - Etap I - Zadanie Czarnoksi??nicy okr?g?ego sto?u notes: 动态规划我的题解http://www.cnblogs.com/TSHugh/p/882

bzoj3713[PA2014]Iloczyn*

bzoj3713[PA2014]Iloczyn 题意: 判断给定的数字能否被表示成两个斐波那契数的乘积.n≤10^9 题解: 开始在想有没有什么根号级算法,后来想知道斐波那契数列10000位有多大,结果爆long long了……实际上斐波那契数列到45位就大于10^9了.所以直接枚举即可. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) fo

BZOJ 3713: [PA2014]Iloczyn( 枚举 )

斐波那契数列<10^9的数很少很少...所以直接暴力枚举就行了... ------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #d

3713: [PA2014]Iloczyn

3713: [PA2014]Iloczyn Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 327  Solved: 181[Submit][Status][Discuss] Description 斐波那契数列的定义为:k=0或1时,F[k]=k:k>1时,F[k]=F[k-1]+F[k-2].数列的开头几项为0,1,1,2,3,5,8,13,21,34,55,…你的任务是判断给定的数字能否被表示成两个斐波那契数的乘积. Input 第一行包含一个

BZOJ3736 : [Pa2013]Karty

显然只需要考虑与障碍点相邻的格子,通过旋转坐标系,可以只考虑障碍点在格子上方的情况. 悬线法求出每个点往上的最长延伸距离$x$,以及往左往右的延伸距离$y$. 那么当$r\geq x$时,$c$至多为$y$. 特别地,当某个点下方也是障碍点的时候,$r$不能超过$x$. 维护出每个$r$对应的最大的$c$即可. 时间复杂度$O(nm)$. #include<cstdio> #include<algorithm> const int N=2505; int n,m,i,j,k,l[N

BZOJ 3736: [Pa2013]Karty

Description 一个0/1矩阵,求能覆盖所有 \(1\) ,同时不覆盖所有 \(0\) 的矩阵,使这个面积最大. Sol DP/悬线法. 首先,所求的矩阵一定可以覆盖所有贴边的悬线. 用悬线法求出,高度为 \(r\) 最大的 \(c\) ,宽度为 \(c\) 最大的高度. 上下左右都要做一遍,然后更新统计答案. 上下的时候统计的是每一个高度,左右的时候统计的是每一个宽度. 这样就可以保证所有矩阵都是一个合法的矩阵了. 我多开了几个数组,发现空间炸了...然后我就开始滚了... Code