zoukankan      html  css  js  c++  java
  • hdu 4610 Cards

    解法:

      假设n分解因式之后的形式是n = a1 ^ b1 * a2 ^ b2 *...*an ^ bn

      它的因子个数就是(b1+1)*(b2+1)*...*(bn+1)

      因子和是(1+a1 ^ 1+..+a1 ^ b1)*(1 + a2 ^ 1 +..+a2 ^ b2 )*..*(1 + an ^ 1 + ... +an ^bn)

      所以因子个数为素数的条件就是只有一个素因子并且b1 + 1为素数;

        因子和为素数的条件就是只有一个素因子并且(1 + a1 ^ 1+..+a 1 ^ b1)为素数

      接下来要判断因子积是不是完全平方数,因为因子都是成对出现的 i * n / i == n。。。只有完全平方数有个例外。。然后根据这个判断就行。

      按照数满足的条件可以分为16种,然后暴力枚举取哪些就行了,要注意的是对于每一种一定要取一个。。。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<bitset>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<vector>
      7 #include<algorithm>
      8 using namespace std;
      9 typedef long long ll;
     10 const int N = (int)4e6+10;
     11 const int M = (int)1e6+10;
     12 typedef pair<int,int> pii;
     13 bool p[N];
     14 int prime[M];
     15 void init(){
     16     memset(p,true,sizeof(p));
     17     p[0] = p[1] = false;
     18     for(int i=2;i*i<N;i++)
     19         for(int j=i;j*i<N;j++)
     20             p[i*j] = 0;
     21     prime[0] = 0;
     22     for(int i=2;i<N;i++)
     23         if(p[i])prime[++prime[0]] = i;
     24 }
     25 vector<pii>factor;
     26 void div(int n){
     27     factor.clear();
     28     for(int i=1;prime[i] * prime[i] <= n;i++){
     29         if(n % prime[i]  == 0){
     30             int cnt = 0;
     31             while(n % prime[i] == 0){
     32                 n /= prime[i];
     33                 ++cnt;
     34             }
     35             factor.push_back(make_pair(prime[i],cnt));
     36         }
     37     }
     38     if(n > 1)factor.push_back(make_pair(n,1));
     39 }
     40 ll Pow(ll a,ll b){
     41     ll ans = 1;
     42     while(b){
     43         if(b&1)ans = ans * a;
     44         a = a * a;
     45         b >>= 1;
     46     }
     47     return ans;
     48 }
     49 bool isPrime_amount(int n){
     50     if(factor.size() > 1|| n==1 )return false;
     51     return p[factor[0].second + 1];
     52 }
     53 bool isPrime_sum(int n){
     54     if(factor.size() > 1|| n== 1)return false;
     55     int a = factor[0].first,b = factor[0].second;
     56     int sum = 1LL*(Pow(a,b+1) - 1) / (a - 1);
     57     return p[sum];
     58 }
     59 bool isSquare(ll n){
     60     ll _ = sqrt(n*1.0);
     61     return _ * _ == n;
     62 }
     63 bool isSquare_product(int n){
     64     int all = 1;
     65     for(int i=0;i<factor.size();i++)
     66         all *= factor[i].second + 1;
     67     ll sq = sqrt(n*1.0);
     68     ll cur = 1;
     69     int p = all >> 1;
     70     if(p & 1)cur *= n;
     71     if(all & 1)cur *= sq;
     72     return isSquare(cur);
     73 }
     74 
     75 int extra[5];
     76 int V[16],cur[5],hash[16];
     77 int have[16];
     78 int main(){
     79     for(int i=0;i<16;i++){
     80         int all = 0;
     81         for(int j=0;j<4;j++)
     82             if(!(i&(1<<j)))++all;
     83         have[i] = all;
     84     }
     85     init();
     86     int T,n,K;
     87     scanf("%d",&T);
     88     while(T--){
     89         memset(V,0,sizeof(V));
     90         scanf("%d%d",&n,&K);
     91         for(int i=1;i<=n;i++){
     92             int a,b;
     93             scanf("%d%d",&a,&b);
     94             int flag = 15,cnt = 0;
     95             div(a);
     96             if(p[a])flag ^= 1<<0 ,cnt ++;//puts("1 ok");
     97             if(isPrime_amount(a)) flag ^= 1<<1,cnt ++;//puts("2 ok");
     98             if(isPrime_sum(a))flag ^= 1<<2,cnt ++;//puts("3 ok");
     99             if(isSquare_product(a)) flag ^= 1<<3,cnt++;//puts("4 ok");
    100             V[flag] += b;
    101             if(i!=1)printf(" ");
    102             printf("%d",cnt);
    103         }
    104         puts("");
    105         int ans = -(~0u>>2);
    106         
    107         for(int i=0;i< 4;i++)scanf("%d",&extra[i]);
    108         for(int i=0;i < 1<<16;i++){
    109             memset(cur,0,sizeof(cur));
    110             int res = K,number = 0,all = 0;
    111             int flag = 15;
    112             for(int j = 0;j < 16;j++){
    113                 if(i&(1<<j)){
    114                     if(V[j] > 0){
    115                         flag &= j;
    116                         res --;
    117                         all += have[j];
    118                         cur[have[j]] += V[j] - 1;
    119                     }else{
    120                         res = -1;
    121                         break;
    122                     }
    123                 }
    124             }
    125             if(res < 0 )continue;
    126             for(int k=4;k >= 0 && res > 0;k--){
    127                 if(cur[k] <= res){
    128                     all += k * cur[k];
    129                     res -= cur[k];
    130                 }else{
    131                     all += res * k;
    132                     res =0;
    133                 }
    134             }
    135             if(res == 0){
    136                 for(int j=0;j<4;j++)
    137                     if(flag & (1<<j))all += extra[j];
    138                 ans = max(ans,all);
    139             }
    140         }
    141 
    142         printf("%d
    ",ans);
    143     }
    144     return 0;
    145 }
  • 相关阅读:
    RP2833 FPGA对应串口标识
    rp2833 网卡以及串口与接插件位置关系
    环境检测 短信收发的测试
    #A号板测试汇总
    #8号板测试汇总
    #2号板测试汇总
    #6号板问题
    【POJ3045】Cow Acrobats(贪心)
    【HDU1219】AC Me(水题)
    BUPT2017 wintertraining(15) #2 题解
  • 原文地址:https://www.cnblogs.com/silver-bullet/p/3227320.html
Copyright © 2011-2022 走看看