HDU 4392 Maximum Number Of Divisors [数学+搜索]
2012-09-23 11:33
661 查看
求比N小的因数最多的数,因数相同时取较小的的。(N<=10^80)
没想法的题目,没想到是搜索。。
首先因子数目 f[i] = ∏(p[i]+1) ,p[i]是所有质因数的个数,这个应该都知道。如果要使因子最多并且数最小,不会用到太大的质数,这个我也不知道怎么证明。。原题解也没有证明。。。
用一个四元组[K,F,N,A[]]表示数K有F个因数,包含N个质因数,每个质因数P[i]分别有A[i]个。然后搜索就可以了,添加一个已有质数A[i],四元组转化为[K*P[i],F/(A[i]+1)*(A[i]+2),N,A[i]+1],添加一个新的质数A[i],四元组转化为,[K*P[i],F*2,N+1,A[i]=1]。
用map存所有的F对应的K,F相同时保留较小的K。
直接做会超时,因为搜索中数是一直递增的,把结果存下来然后离线边搜边更新结果就A了,估计是因为case不多但都是大数据。。。
没想法的题目,没想到是搜索。。
首先因子数目 f[i] = ∏(p[i]+1) ,p[i]是所有质因数的个数,这个应该都知道。如果要使因子最多并且数最小,不会用到太大的质数,这个我也不知道怎么证明。。原题解也没有证明。。。
用一个四元组[K,F,N,A[]]表示数K有F个因数,包含N个质因数,每个质因数P[i]分别有A[i]个。然后搜索就可以了,添加一个已有质数A[i],四元组转化为[K*P[i],F/(A[i]+1)*(A[i]+2),N,A[i]+1],添加一个新的质数A[i],四元组转化为,[K*P[i],F*2,N+1,A[i]=1]。
用map存所有的F对应的K,F相同时保留较小的K。
直接做会超时,因为搜索中数是一直递增的,把结果存下来然后离线边搜边更新结果就A了,估计是因为case不多但都是大数据。。。
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <map> #include <queue> #include<string> #include<iostream> #define MAXN 200 using namespace std; typedef long long LL; const int BMOD = 100000000; const int maxl = (MAXN>>3)+1; struct bign{ int s[maxl], len; void init(){memset(s, 0, sizeof s); len = 1;} void clean(){while(len > 1 && !s[len-1]) --len;} bign(){init();} bign(int num){*this = num;} bign(const char *num){*this = num;} bign operator = (int num) { char s[maxl]; sprintf(s, "%d", num); return *this = s; } bign operator = (const char *buf) { init(); int l = strlen(buf); for(int i = 0, j = l - 1; i < l; ++ i, -- j) s[j >> 3] = s[j >> 3] * 10 + buf[i] - '0'; len = (l >> 3) + 1; clean(); return *this; } bign operator + (const bign b) { bign c; c.len = 0; int g = 0; for (int i = 0; g || i < max(len, b.len); i++) { c.s[c.len] = g; if(i < len)c.s[c.len] += s[i]; if(i < b.len)c.s[c.len] +=b.s[i]; g = c.s[c.len]/BMOD, c.s[c.len] %= BMOD, c.len++; } return c; } bign operator * (const bign b) { bign c; c.len = len + b.len; LL lin; for (int i = 0; i < len; i++) for (int j = 0; j < b.len; j++){ lin = (LL)s[i] * b.s[j] + c.s[i+j]; c.s[i+j] = lin % BMOD; c.s[i+j+1] += lin / BMOD; } for (int i = 0; i < c.len - 1; i++) c.s[i+1] += c.s[i] / BMOD, c.s[i] %= BMOD; c.clean(); return c; } bool operator <(const bign b) const{ if(len != b.len) return len < b.len; for (int i = len - 1; i >= 0; i--) if (s[i] != b.s[i]) return s[i] < b.s[i]; return false; } bool operator <=(const bign b) const {return !(b < *this);} void print() { for(int i = len - 1; i >= 0; i--) { if (i == len - 1) printf("%d", s[i]); else printf("%08d", s[i]); } } }; struct stt{ bign k; LL f; int n,a[MAXN]; stt(){} stt(bign kk, LL ff, int nn) {k = kk, f= ff, n = nn;} }; struct ans{ bign in, res; LL f; }; map<LL, bign> mp; vector<ans> vec; bign maxp, pri[MAXN]; int prs; //pri[i]和stt里的a[i]是对应的,a[i]是pri[i]的个数 void init() { prs = 0; for (int i = 2, j, flag; i < MAXN; i++) { for (flag = 1,j = 2; j < i; j++) if (i % j == 0) flag = 0; if (flag) pri[prs++] = i; } } bool canadd(stt st) { if (maxp < st.k) return false; if (mp.find(st.f) == mp.end() || st.k < mp[st.f]){ mp[st.f] = st.k; return true; } return false; } void updateans(stt st) { for (int i = 0; i < vec.size(); i++) { if (st.k <= vec[i].in && (st.f > vec[i].f || st.f == vec[i].f && st.k < vec[i].res)) vec[i].res = st.k, vec[i].f = st.f; } } void bfs(){ queue<stt> q; mp.clear(); mp[1] = 1; q.push(stt(1, 1, 0)); while (!q.empty()) { stt ost = q.front(); q.pop(); updateans(ost); //添加已有质数 for (int i = 0 ; i < ost.n; i++) { stt nst = ost; nst.k = ost.k * pri[i]; nst.f = ost.f / (ost.a[i]+1) * (ost.a[i]+2); nst.a[i]++; if (canadd(nst)) q.push(nst); } //添加还未添加的质数 stt nst = ost; nst.k = ost.k * pri[ost.n]; nst.f = ost.f * 2; nst.a[nst.n++] = 1; if (canadd(nst)) q.push(nst); } } char s[MAXN]; int main() { //freopen("test.in","r",stdin); init(); maxp = 0; vec.clear(); mp.clear(); while (scanf("%s", s) != EOF) { ans a; a.in = s, a.res = 1, a.f = 1; if (maxp < a.in) maxp = a.in; vec.push_back(a); } bfs(); for (int i = 0; i < vec.size(); i++) vec[i].res.print(), printf(" %I64d\n",vec[i].f); return 0; }
相关文章推荐
- hdu 4392 Maximum Number Of Divisors
- hdu 1492 The number of divisors(约数) about Humble Numbers (数学:排列组合)
- HDU 1492 The number of divisors(约数) about Humble Numbers(数学题)
- HDU 3006 The Number of set (搜索+位压缩)
- HDU 1492 The number of divisors(约数) about Humble Numbers (约数个数)
- HDU1492 The number of divisors(约数) about Humble Numbers【约数】
- hdu1492-The number of divisors(约数) about Humble Numbers
- HDU 1492 The number of divisors(约数) about Humble Numbers
- ACM 数论 hdu 1492 The number of divisors(约数) about Humble Numbers
- CodeForces - 27E Number With The Given Amount Of Divisors (DFS+数学)
- HDU 1492 The number of divisors(约数) about Humble Numbers
- HDU 1492 The number of divisors(约数) about Humble Numbers
- hdu1492 The number of divisors(约数) about Humble Numbers(公约数个数问题)
- HDU 1492 The number of divisors(约数) about Humble Numbers(数论题目要知道定理呀....)
- HDU1492 The number of divisors(约数) about Humble Numbers
- Maximum Number Of Divisors
- HDU1492-The number of divisors(约数) about Humble Numbers-数论(计数问题)
- HDU 1492 The number of divisors(约数) about Humble Numbers 水题
- Ccodeforces 27E Number With The Given Amount Of Divisors(数论+搜索)
- hdu1492 The number of divisors(约数) about Humble Numbers