[数]被数学淹没不知所措

啊假期结束了 , 可以休息一阵子了
UVA-10892分解&选择
#include#include#includeusing namespace std;typedef long long ll;bool isp[1000005];int p[80005];int f[100005];int m,co;void pri(){co = 0;for (int i = 2; i < 1000005; i++)isp[i] = 1;for (int i = 2; i < 1000005; i++) {if (isp[i])p[co++] = i;for (int j = 0; j < co&&i*p[j] < 1000005; j++)isp[i*p[j]] = 0;}}void d(ll n){m = 0;for (int i=0; i> n && n) {memset(f, 0, sizeof(f));d(n);ll ans = 1;for (int i = 0; i < m; i++)ans *= f[i] * 2 + 1;ans = (ans + 1) / 2;cout << n << " " << ans << endl;}return 0;}
UVA-10892
把给出的数分解质因数 , 然后考虑分别分配给两个数 , 这样可得最小公倍数为n 。
我没有什么别的想法 , 我觉得题解说的有道理 。
UVA-11752我觉得头大
找出所有2^64以下的均能由两个不同的数的次方构成的数 。
一个是从头到尾枚举底数枚举次数来一遍 。一开始没想到怎么解决从小到大的问题 , 后来发现重复的问题也解决不了 。题解告诉我这不就是set了嘛 。
#include#include#include#include#includeusing namespace std;typedef unsigned long long ull;bool np[100];int p[100];void cpl(){int co = 0;for (int i = 2; i < 65; i++) {if (!np[i])p[co++] = i;for (int j = 0; j < co&&i*p[j] < 65; j++) {np[i*p[j]] = 1;}}}int main(){setans;cpl();ans.insert(1);int m = 1 << 16;ull t = -1;for (int i = 2; i <= m; i++) {ull a = 1;for (int j = 1; j < 64; j++) {a *= i;if (np[j])ans.insert(a);if (a > t / i)break;}}set::iterator i;for (i = ans.begin(); i != ans.end(); i++)cout << *i << endl;return 0;}
UVA-11752枚举跳出
另一个是换底公式把当前底数的最大次数算出来再枚举 。这个方式卡了自己好久 , 最后发现是因为合数表(?)打出来的时候并不是按照从小到大的顺序 , 直接导致在后面循环乘的时候疯狂乘爆(其实这个也可以通过三目运算符来解决:(a[j]-a[j-1]==1)?*i:*i*i , 我就是不想写三目运算符哼╭(╯^╰)╮)
#include#include#include#include#includeusing namespace std;typedef unsigned long long ull;bool np[100];int a[100],p[100];void cpl(){int co = 0,cc=0;for (int i = 2; i < 65; i++) {if (!np[i])p[co++] = i;for (int j = 0; j < co&&i*p[j] < 65; j++) np[i*p[j]] = 1;}for (int i = 2; i < 65; i++) if (np[i])a[cc++] = i;//sort(a, a + cc);}int main(){setans;cpl();ans.insert(1);int ma = 1 << 16;for (ull i = 2; i <= ma; i++) {int m = ceil(64 * log(2) / log(i)) - 1;ull an = i * i * i * i;if(i!=ma)ans.insert(an);for (int j = 1; a[j] <= m; j++) {for (int k = 0; k < a[j] - a[j - 1]; k++)an *= i;ans.insert(an);}}set::iterator i;for (i = ans.begin(); i != ans.end(); i++)cout << *i << endl;return 0;}
UVA-11752换底
对了 , 重新排序的时候扫一遍应该会比sort快一丢丢 。
UVA-10780我觉得头极大
一开始自己推了个规律结果发现没考虑到6 4这样的状况 , 也就是有因子没本身的时候 , 好 , 那我就把因子分解出来 。
然后就有一些奇奇怪怪的错误 , 然后把ans从改到 , 又改min , 又改输出条件……反正最后就这样了
#include#include#include#includeusing namespace std;int t, n, m;int fa[10050];void got(int n){for (int i = 2; i*i <= n; i++) {while (n%i == 0) {fa[i]++;n /= i;}}fa[n]++;}int main(){cin >> t;for (int i = 1; i <= t; i++) {memset(fa, 0, sizeof(fa));cin >> m >> n;int ans = 0x3f3f3f3f;for (int j = 2; j <= n; j++) {got(j);}int co;for (int j = 2; j <= m; j++) {co = 0;while (m%j == 0) {co++;m /= j;}if (co)ans = min(ans, fa[j] / co);}//ans = min(ans, fa[m]);if (ans)printf("Case %d:\n%d\n", i, ans);else printf("Case %d:\nImpossible to divide\n", i);}return 0;}