2015 HNU warm up 02
来源:互联网 发布:电脑病毒 变更mac地址 编辑:程序博客网 时间:2024/05/18 02:04
D - Four-Tower Towers of Hanoi
E - Light Switches
假设在4个柱子上挪n个个盘子的最小步骤是F[n],在三个柱子上挪n个盘子的最小步骤是T[n],则四柱汉诺塔问题,可以分成两部分考虑:
1.先把上面k个盘子用F[k]步挪到B盘;
2.把下面n-k个盘子用T[n-k]步挪到D盘;
3.把B盘上的k个盘子再用F[k]步挪到D盘。
所以可以得到递推式 F[n] = min{ 2 * F[k] + T[n-k] }。
T[n]的公式已经推出:2^n - 1。
题目还有一个要注意的地方:虽然题目保证最后答案不会超过int64的范围,但是计算过程却可能会。
//code source from sk#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>using namespace std;const int maxn = 1005;const unsigned __int64 INF = ((__int64)0 - 1);unsigned __int64 dp[maxn];unsigned __int64 two[maxn];void init(){ two[0] = 1; for(int i = 1; i < maxn; i++) two[i] = two[i-1]*2; dp[0] = 0; dp[1] = 1; dp[2] = 3; dp[3] = 5; dp[4] = 9; dp[5] = 13; for(int i = 6; i < maxn; i++) { unsigned __int64 p = INF; for(int k = i-1; k < i && i-k < 62; k--) p = min(p, dp[k]*2+two[i-k]-1); dp[i] = p; }// for(int i = 1; i < maxn; i++)// cout << "dp[" << i << "]:" << dp[i] << endl;}int main(){ init(); int n; int kase = 1; while(scanf("%d", &n)!=EOF) { printf("Case %d: %I64d\n", kase++, dp[n]); } return 0;}
E - Light Switches
大素数判定 + dfs所有约数
代码许多地方参考了小伙伴的源码还有shoutmon学长的模板。
#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <math.h>#include <time.h>using namespace std;#define LL __int64#define INF 99999999999999LL#define Rand_time 5#define C 16381bool cmp(LL a, LL b){ return a < b;}LL MIN;LL gcd(LL a, LL b){ return a % b ? gcd(b, a % b) : b;}//(a * b) % nLL Multi_mod(LL a, LL b, LL n){ LL s = 0; while(b) { if(b & 1) s = (s + a) % n; a = (a + a) % n; b >>= 1; } return s;}//(a ^ b) % nLL Pow_mod(LL a, LL b, LL n){ LL s = 1; while(b) { if(b & 1) s = Multi_mod(s, a, n); a = Multi_mod(a, a, n); b >>= 1; } return s;}//默认1为合数bool Miller_Rabin(LL n){ LL u = n - 1, pre, x; if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11) return true; if(n == 1 || !(n % 2) || !(n % 3) || !(n % 5) || !(n % 7) || !(n % 11)) return false; //把 n-1 分解成 k 个 2 和 奇数 v 的乘积 //则可以把计算 a ^ (n-1) % n,分解成计算 k 次 (a^2) 迭代计算和 a^v % n 的计算 int k = 0; while(!(u & 1)) u >>= 1, k++; srand((LL)time(NULL)); for(int i = 0; i < Rand_time; i++) { x = rand() % (n - 2) + 2; x = Pow_mod(x, u, n); pre = x; //保留x,既x^2 mod n =1 的根 for(int j = 0; j < k; j++) { x = Multi_mod(x, x, n); //如果n是素数那么 x^2mod n = 1,仅有两个根(不同余),+1和-1(n-1) if(x == 1 && pre != 1 && pre != (n - 1)) return false; pre = x; } if(x != 1) return false; } return true;}//在O(sqrt(p))的时间复杂度内找到n的一个小因子pLL Pollard_rho(LL n, int c){ LL x, y, d; int i = 1, j = 2; srand((LL)time(NULL)); x = rand() % (n - 1) + 1; y = x; while(1) { i++; x = (Multi_mod(x, x, n) + c) % n; d = gcd(y - x + n, n); if(d != 1 && d != n) return d; if(x == y) return n; if(i == j) { y = x; j <<= 1; } }}//求所有素因子LL fac[100];int cnt[100], k, ck;void find_factor(LL n, int c){ LL r, d; if(n <= 1) return ; if(Miller_Rabin(n)) { fac[k++] = n; return ; } r = Pollard_rho(n, c--); d = n / r; find_factor(d, c); find_factor(r, c);}LL n, t, b;void deal(){ k = ck = 0; find_factor(b, C); sort(fac, fac + k, cmp); cnt[0] = 1; for(int i = 1; i < k; i++) { if(fac[i] == fac[ck]) cnt[ck]++; else { fac[++ck] = fac[i]; cnt[ck] = 1; } } ck++;}LL yinzi[12345];int num;void dfs(LL val, int k){ if(k == ck) { yinzi[num++] = val; return ;} for(int i = 0, v = 1; i <= cnt[k]; i++) { dfs(val * v, k + 1); v *= fac[k]; }}char res[2][4] = {"On", "Off"};int cas = 0;void prt(int w){ printf("Case %d: %s\n", ++cas, res[w]);}int main(){// freopen("Light_Switches.in", "r", stdin); while(~scanf("%I64d%I64d%I64d", &n, &t, &b)) { t %= n; if(!t) t = n; if(b == 1LL) { prt(0); continue; } if(Miller_Rabin(b)) { if(t >= b) prt(1); else prt(0); continue; } deal(); num = 0; dfs(1, 0); sort(yinzi, yinzi + num, cmp);// for(int i = 0; i < num; i++) cout << yinzi[i] << ' '; cout << endl; int id = lower_bound(yinzi, yinzi + num, t) - yinzi; prt((id + 1) & 1); } return 0;}
0 0
- 2015 HNU warm up 02
- 2015 HNU Warm Up 01
- 2015 HNU warm up 03
- 2015 HNU Warm Up 04
- 2015 HNU Warm Up 06
- 2015 HNU warm up 05
- 2015 HNU warm up 07
- 2015 HNU warm up 12
- Bayan 2015 Contest Warm Up
- Bayan 2015 Contest Warm Up
- Bayan 2015 Contest Warm Up (D题)
- [Warm-up] Homework
- [Introduction and Warm-up]
- hdu 4612 Warm up
- HDU 4612 Warm up
- HDOJ 4612: Warm up
- hdu 4612 Warm up
- D - Warm up 2
- 将Eclipse代码导入到AndroidStudio的两种方式...
- 用proguard混淆java web项目
- 手机QQ内置浏览器position:fixed 属性支持不好的解决方案
- windows服务和进程的区别和联系
- App Manifest:<application> android:largeHeap
- 2015 HNU warm up 02
- 推荐的 CSS 书写顺序--个人建议
- 2014工作总结
- (十四)单组数据展示(字典转模型、模型初始化细节)
- 笔试之循环递增数组查找
- 视图的更新
- Android签名详解(debug和release)
- Eclipse设置默认编码
- 虚拟机中文版设置说明