From 2eda91854a4d5de94577fa34b2b52a04a0a84ff8 Mon Sep 17 00:00:00 2001 From: zhangzc Date: Fri, 29 Oct 2021 10:53:21 +0800 Subject: [PATCH] update exercises --- .../solution.cpp" | 2 +- .../solution.md" | 138 +++++++++++++++++- .../solution.md" | 2 +- .../desc.md" | 4 +- .../solution.cpp" | 91 +++--------- .../solution.md" | 108 +++++++++++++- .../solution.md" | 8 +- .../solution.md" | 80 +++++----- 8 files changed, 308 insertions(+), 125 deletions(-) diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.cpp" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.cpp" index 63ec7e2b..6f4fcd14 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.cpp" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.cpp" @@ -44,7 +44,7 @@ int main() { if (i * 2 + 1 <= n) { - dp[i] = (C(s[i] - 1, s[i * 2 + 1]) * dp[i * 2 + 1]) % mod * dp[i * 2] % mod; + dp[i] = (C(s[i], s[i * 2]) * dp[i * 2]) % mod * dp[i * 2] % mod; } } cout << dp[1] << endl; diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.md" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.md" index eab71141..e366d8af 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.md" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\240\206\347\232\204\350\256\241\346\225\260/solution.md" @@ -56,7 +56,31 @@ CPU消耗 < 1000ms ## aop ### before ```cpp - +#include +using namespace std; +typedef long long ll; +const int maxn = 100000; +ll s[maxn + 10], dp[maxn + 10], inv[maxn + 10], f[maxn + 10]; +ll n; +ll mod = 1000000009; +ll qPow(ll a, ll b) +{ + ll ans = 1; + while (b != 0) + { + if (b & 1) + { + ans = ans * a % mod; + } + a = a * a % mod; + b >>= 1; + } + return ans % mod; +} +ll C(ll n, ll m) +{ + return (f[n] * inv[f[m]]) % mod * inv[f[n - m]] % mod; +} ``` ### after ```cpp @@ -65,21 +89,125 @@ CPU消耗 < 1000ms ## 答案 ```cpp - +int main() +{ + cin >> n; + f[0] = 1; + for (int i = 1; i <= maxn; i++) + { + f[i] = (f[i - 1] * i) % mod; + inv[i] = qPow(i, mod - 2); + } + for (int i = n; i >= 1; i--) + { + s[i] = (s[i * 2 + 1] <= n ? s[i * 2 + 1] : 0) + (s[i * 2] <= n ? s[i * 2] : 0) + 1; + } + for (int i = 1; i <= n; i++) + { + dp[i] = 1; + } + for (int i = n; i >= 1; i--) + { + if (i * 2 + 1 <= n) + { + dp[i] = (C(s[i] - 1, s[i * 2 + 1]) * dp[i * 2 + 1]) % mod * dp[i * 2] % mod; + } + } + cout << dp[1] << endl; + return 0; +} ``` ## 选项 ### A ```cpp - +int main() +{ + cin >> n; + f[0] = 1; + for (int i = 1; i <= maxn; i++) + { + f[i] = (f[i - 1] * i) % mod; + inv[i] = qPow(i, mod - 2); + } + for (int i = n; i >= 1; i--) + { + s[i] = (s[i * 2 + 1] <= n ? s[i * 2 + 1] : 0) + (s[i * 2] <= n ? s[i * 2] : 0) + 1; + } + for (int i = 1; i <= n; i++) + { + dp[i] = 1; + } + for (int i = n; i >= 1; i--) + { + if (i * 2 + 1 <= n) + { + dp[i] = (C(s[i] - 1, s[i * 2 - 1]) * dp[i * 2 + 1]) % mod * dp[i * 2] % mod; + } + } + cout << dp[1] << endl; + return 0; +} ``` ### B ```cpp - +int main() +{ + cin >> n; + f[0] = 1; + for (int i = 1; i <= maxn; i++) + { + f[i] = (f[i - 1] * i) % mod; + inv[i] = qPow(i, mod - 2); + } + for (int i = n; i >= 1; i--) + { + s[i] = (s[i * 2 + 1] <= n ? s[i * 2 + 1] : 0) + (s[i * 2] <= n ? s[i * 2] : 0) + 1; + } + for (int i = 1; i <= n; i++) + { + dp[i] = 1; + } + for (int i = n; i >= 1; i--) + { + if (i * 2 + 1 <= n) + { + dp[i] = (C(s[i] - 1, s[i * 2 - 1]) * dp[i * 2 - 1]) % mod * dp[i * 2] % mod; + } + } + cout << dp[1] << endl; + return 0; +} ``` ### C ```cpp - +int main() +{ + cin >> n; + f[0] = 1; + for (int i = 1; i <= maxn; i++) + { + f[i] = (f[i - 1] * i) % mod; + inv[i] = qPow(i, mod - 2); + } + for (int i = n; i >= 1; i--) + { + s[i] = (s[i * 2 + 1] <= n ? s[i * 2 + 1] : 0) + (s[i * 2] <= n ? s[i * 2] : 0) + 1; + } + for (int i = 1; i <= n; i++) + { + dp[i] = 1; + } + for (int i = n; i >= 1; i--) + { + if (i * 2 + 1 <= n) + { + dp[i] = (C(s[i], s[i * 2]) * dp[i * 2]) % mod * dp[i * 2] % mod; + } + } + cout << dp[1] << endl; + return 0; +} ``` diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\247\346\225\260\344\271\230\346\263\225/solution.md" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\247\346\225\260\344\271\230\346\263\225/solution.md" index 09d02398..28453656 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\247\346\225\260\344\271\230\346\263\225/solution.md" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\247\346\225\260\344\271\230\346\263\225/solution.md" @@ -1,7 +1,7 @@ # 大数乘法 对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”。 -![](https: +![](https://img-blog.csdn.net/20160125091111485) 上图表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数。可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正。 diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/desc.md" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/desc.md" index 56d5fc07..290e63f3 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/desc.md" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/desc.md" @@ -10,7 +10,9 @@ ``` 数据含义:甲对乙的取胜概率为0.1,丙对乙的胜率为0.3,... -现在要举行一次锦标赛。双方抽签,分两个组比,获胜的两个队再争夺冠军。(参见【1.jpg】) +现在要举行一次锦标赛。双方抽签,分两个组比,获胜的两个队再争夺冠军。 + +![](https://img-blog.csdn.net/20150228234310457?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3IxMzI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 请你进行10万次模拟,计算出甲队夺冠的概率。 diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.cpp" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.cpp" index 3e93baa8..32c05c80 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.cpp" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.cpp" @@ -1,74 +1,31 @@ -#include -#include -int main(void) -{ - int i, j, k; //count - int randfigure; - int awin = 0; +#include +using namespace std; +double rate[4][4] = { + {0, 0.1, 0.3, 0.5}, + {0.9, 0, 0.7, 0.4}, + {0.7, 0.3, 0, 0.2}, + {0.5, 0.6, 0.8, 0}}; - for (i = 0; i < 100000; i++) +int main() +{ + int i, j, k; + double time, sum; + time = 0; + sum = 0; + for (i = 1; i < 4; i++) { - randfigure = rand(); - if (randfigure % 3 == 0) - { //AB together - if (randfigure % 10 < 1) - { //A win B - if (randfigure % 10 < 2) - { //C win D - if (randfigure % 10 < 3) - { //A win C - awin++; - } - } - else - { //D win C - if (randfigure % 10 < 5) - { //A win D - awin++; - } - } - } - } - else if (randfigure % 3 == 1) - { //AC together - if (randfigure % 10 < 3) - { //A win C - if (randfigure % 10 < 4) - { //B win D - if (randfigure % 10 < 1) - { //A win B - awin++; - } - } - else - { //D win B - if (randfigure % 10 < 5) - { //A win D - awin++; - } - } - } - } - else - { //AD together - if (randfigure % 10 < 5) - { //A win D - if (randfigure % 10 < 3) - { //C win B - if (randfigure % 10 < 3) - { //A win C - awin++; - } - } - else - { //B win C - if (randfigure % 10 < 1) - { //A win B - awin++; - } + for (j = 1; j < 4; j++) + { + for (k = 1; k < 4; k++) + { + if (j != i && k != i && j != k) + { + sum += rate[0][i] * rate[j][k]; } } } + time++; } - printf("%f\n", awin / 100000.0); + cout << sum / time; + return 0; } \ No newline at end of file diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.md" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.md" index f70c6936..abbe6e99 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.md" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\345\244\272\345\206\240\346\246\202\347\216\207/solution.md" @@ -11,7 +11,9 @@ ``` 数据含义:甲对乙的取胜概率为0.1,丙对乙的胜率为0.3,... -现在要举行一次锦标赛。双方抽签,分两个组比,获胜的两个队再争夺冠军。(参见【1.jpg】) +现在要举行一次锦标赛。双方抽签,分两个组比,获胜的两个队再争夺冠军。 + +![](https://img-blog.csdn.net/20150228234310457?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3IxMzI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 请你进行10万次模拟,计算出甲队夺冠的概率。 @@ -20,7 +22,13 @@ ## aop ### before ```cpp - +#include +using namespace std; +double rate[4][4] = { + {0, 0.1, 0.3, 0.5}, + {0.9, 0, 0.7, 0.4}, + {0.7, 0.3, 0, 0.2}, + {0.5, 0.6, 0.8, 0}}; ``` ### after ```cpp @@ -29,21 +37,109 @@ ## 答案 ```cpp - +int main() +{ + int i, j, k; + double time, sum; + time = 0; + sum = 0; + for (i = 1; i < 4; i++) + { + for (j = 1; j < 4; j++) + { + for (k = 1; k < 4; k++) + { + if (j != i && k != i && j != k) + { + sum += rate[0][i] * rate[j][k] * rate[0][j]; + } + } + } + time++; + } + cout << sum / time; + return 0; +} ``` ## 选项 ### A ```cpp - +int main() +{ + int i, j, k; + double time, sum; + time = 0; + sum = 0; + for (i = 1; i < 4; i++) + { + for (j = 1; j < 4; j++) + { + for (k = 1; k < 4; k++) + { + if (j != i && k != i && j != k) + { + sum += rate[0][i] * rate[0][j]; + } + } + } + time++; + } + cout << sum / time; + return 0; +} ``` ### B ```cpp - +int main() +{ + int i, j, k; + double time, sum; + time = 0; + sum = 0; + for (i = 1; i < 4; i++) + { + for (j = 1; j < 4; j++) + { + for (k = 1; k < 4; k++) + { + if (j != i && k != i && j != k) + { + sum += rate[j][k] * rate[0][j]; + } + } + } + time++; + } + cout << sum / time; + return 0; +} ``` ### C ```cpp - +int main() +{ + int i, j, k; + double time, sum; + time = 0; + sum = 0; + for (i = 1; i < 4; i++) + { + for (j = 1; j < 4; j++) + { + for (k = 1; k < 4; k++) + { + if (j != i && k != i && j != k) + { + sum += rate[0][i] * rate[j][k]; + } + } + } + time++; + } + cout << sum / time; + return 0; +} ``` diff --git "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\347\255\211\350\205\260\344\270\211\350\247\222\345\275\242/solution.md" "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\347\255\211\350\205\260\344\270\211\350\247\222\345\275\242/solution.md" index 2625353c..44956664 100644 --- "a/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\347\255\211\350\205\260\344\270\211\350\247\222\345\275\242/solution.md" +++ "b/data/1.\347\256\227\346\263\225\345\210\235\351\230\266/1.\350\223\235\346\241\245\346\235\257/\347\255\211\350\205\260\344\270\211\350\247\222\345\275\242/solution.md" @@ -4,7 +4,7 @@ 先用1,2,3,…的自然数拼一个足够长的串 用这个串填充三角形的三条边。从上方顶点开始,逆时针填充。 比如,当三角形高度是8时: -![](https: +![](https://img-blog.csdnimg.cn/20190203174943179.png) 输入,一个正整数n(3 -300 && after_reverse - before_reverse < -200) - //在200-300范围内,我们以正数为准 + { profit1[i][0] = before_reverse; profit1[i][1] = after_reverse - before_reverse; i++; } else if (after_reverse - before_reverse > 800 && after_reverse - before_reverse < 900) - //在800-900范围内 + { profit1[j][0] = before_reverse; profit2[j][1] = after_reverse - before_reverse; @@ -84,15 +84,15 @@ int main() ```cpp int main() { - int num1[7] = {0, 1, 2, 5, 6, 8, 9}; //价牌包含的数字 - int num2[7] = {0, 1, 2, 5, 9, 8, 6}; //价牌翻转对应的数字 - int profit1[1111][2]; //利润1 - int profit2[1111][2]; //利润2 - int before_reverse; //颠倒前 - int after_reverse; //颠倒后 + int num1[7] = {0, 1, 2, 5, 6, 8, 9}; + int num2[7] = {0, 1, 2, 5, 9, 8, 6}; + int profit1[1111][2]; + int profit2[1111][2]; + int before_reverse; + int after_reverse; int i = 0; int j = 0; - for (int a = 1; a < 7; a++) //从1开始,第一位数字不可以是0 + for (int a = 1; a < 7; a++) { for (int b = 0; b < 7; b++) { @@ -102,16 +102,16 @@ int main() { before_reverse = num1[a] * 1000 + num1[b] * 100 + num1[c] * 10 + num1[d]; after_reverse = num2[d] * 1000 + num2[c] * 100 + num2[b] * 10 + num2[a]; - //因为是颠倒之后所以第一位可以是0 + if (after_reverse - before_reverse > -300 && after_reverse - before_reverse < -200) - //在200-300范围内,我们以正数为准 + { profit1[i][0] = before_reverse; profit1[i][1] = after_reverse - before_reverse; i++; } else if (after_reverse - before_reverse > 800 && after_reverse - before_reverse < 900) - //在800-900范围内 + { profit1[j][0] = before_reverse; profit2[j][1] = after_reverse - before_reverse; @@ -141,15 +141,15 @@ int main() ```cpp int main() { - int num1[7] = {0, 1, 2, 5, 6, 8, 9}; //价牌包含的数字 - int num2[7] = {0, 1, 2, 5, 9, 8, 6}; //价牌翻转对应的数字 - int profit1[1111][2]; //利润1 - int profit2[1111][2]; //利润2 - int before_reverse; //颠倒前 - int after_reverse; //颠倒后 + int num1[7] = {0, 1, 2, 5, 6, 8, 9}; + int num2[7] = {0, 1, 2, 5, 9, 8, 6}; + int profit1[1111][2]; + int profit2[1111][2]; + int before_reverse; + int after_reverse; int i = 0; int j = 0; - for (int a = 1; a < 7; a++) //从1开始,第一位数字不可以是0 + for (int a = 1; a < 7; a++) { for (int b = 0; b < 7; b++) { @@ -159,16 +159,16 @@ int main() { before_reverse = num1[a] * 1000 + num1[b] * 100 + num1[c] * 10 + num1[d]; after_reverse = num2[d] * 1000 + num2[c] * 100 + num2[b] * 10 + num2[a]; - //因为是颠倒之后所以第一位可以是0 + if (after_reverse - before_reverse > -300 && after_reverse - before_reverse < -200) - //在200-300范围内,我们以正数为准 + { profit1[i][0] = before_reverse; profit1[i][1] = after_reverse - before_reverse; i++; } else if (after_reverse - before_reverse > 800 && after_reverse - before_reverse < 900) - //在800-900范围内 + { profit1[j][0] = before_reverse; profit2[j][1] = after_reverse - before_reverse; @@ -198,15 +198,15 @@ int main() ```cpp int main() { - int num1[7] = {0, 1, 2, 5, 6, 8, 9}; //价牌包含的数字 - int num2[7] = {0, 1, 2, 5, 9, 8, 6}; //价牌翻转对应的数字 - int profit1[1111][2]; //利润1 - int profit2[1111][2]; //利润2 - int before_reverse; //颠倒前 - int after_reverse; //颠倒后 + int num1[7] = {0, 1, 2, 5, 6, 8, 9}; + int num2[7] = {0, 1, 2, 5, 9, 8, 6}; + int profit1[1111][2]; + int profit2[1111][2]; + int before_reverse; + int after_reverse; int i = 0; int j = 0; - for (int a = 1; a < 7; a++) //从1开始,第一位数字不可以是0 + for (int a = 1; a < 7; a++) { for (int b = 0; b < 7; b++) { @@ -216,16 +216,16 @@ int main() { before_reverse = num1[a] * 1000 + num1[b] * 100 + num1[c] * 10 + num1[d]; after_reverse = num2[d] * 1000 + num2[c] * 100 + num2[b] * 10 + num2[a]; - //因为是颠倒之后所以第一位可以是0 + if (after_reverse - before_reverse > -300 && after_reverse - before_reverse < -200) - //在200-300范围内,我们以正数为准 + { profit1[i][0] = before_reverse; profit1[i][1] = after_reverse - before_reverse; i++; } else if (after_reverse - before_reverse > 800 && after_reverse - before_reverse < 900) - //在800-900范围内 + { profit1[j][0] = before_reverse; profit2[j][1] = after_reverse - before_reverse; -- GitLab