藍橋杯練習題(二)
n!的位數
將n!表示成10的次冪,即n!=10^M(10的M次方),則不小於M的最小整數就是 n!的位數,對該式兩邊取對數,有 M =log10^n!
由公式log(a*b)=loga+logb,可化為:M = log10^1+log10^2+log10^3...+log10^n
最後將得到的M加上1就是n!的位數。(因為是10^M,所以最後位數要+1)
/* n!位數 */ void problem1() { int n, i; double d; while (scanf("%d", &n)) { if (n == EOF) break; d = 0; for (i = 1;i <= n;i++) { d += (double)log10(i); } printf("%d\n", (int)d + 1); } return; }
方法①:其實就是拆分,10可以拆成2*5,所以我們統計所有乘數的因數裡min[ n(2) , n(5) ]的個數即可。但階乘有點特殊的是,5的前面必定有個2(的倍數),故我們求所有乘數的因數裡5的個數即可。
方法②:百度後瞭解的,分享一下:
基於方法①,易得10!裡因數5的個數為2 [ 10/5 ];
而25!裡因數5的個數為6,這是因為25=5*5,即25多提供了一個5 [ 25/5 + 25/(5*5) ];
像125=5*5*5,則125多提供了兩個5,所以125!裡因數5的個數為: 31 [ 125/5 + 125/(5*5) + 125/(5*5*5) ]。
故,推導公式如下:
while (N)
{
N /= 5;
count += N;
}
/* 求n!末尾0的個數 */ void problem2() { int N, i, mod5, d5, count0 = 0; scanf("%d", &N); /* 方法① */ for (i = 1;i <= N;i++) { mod5 = i % 5; d5 = i / 5; while (mod5 == 0) { count0++; mod5 = d5 % 5; d5 /= 5; } } /* 方法② */ count0 = 0; while (N) { N /= 5; count0 += N; } printf("%d!的個數 %d\n", N, count0); }
有一隻經過訓練的蜜蜂只能爬向右側相鄰的蜂房,不能反向爬行。請程式設計計算蜜蜂從蜂房a爬到蜂房b的可能路線數。
其中,蜂房的結構如下所示:
【輸入格式】
輸入資料的第一行是一個整數N,表示測試例項的個數,然後是N 行資料,每行包含兩個整數a和b(0<a<b<50)。
【輸出格式】
對於每個測試例項,請輸出蜜蜂從蜂房a爬到蜂房b的可能路線數,每個例項的輸出佔一行。
【樣例輸入】
2 1 2 3 6
【樣例輸出】
1 3
方法①:簡單粗暴地把上下行可能的走法都實現一次,到達終點就輸出。注意出口設定。
方法②:除了格子1和格子2,其餘數字都是由上個數字走過來或上上個數字走過來,故而累加即可。
/* 一隻小蜜蜂.. */
/* 題目連結 http://acm.hdu.edu.cn/showproblem.php?pid=2044 */
int sum_bees = 0; //一隻小蜜蜂
void Bees(int a1, int a2, int b1, int b2) //遞推,a1起始行,a2起始列,b1終點行,b2終點列
{
if (a1 == b1 && a2 == b2) { //到達離開
sum_bees += 1;
return;
}
if (a2 > b2) return; //剪枝
if (a1 % 2) //下行
{
Bees(a1 - 1, a2 + 1, b1, b2);
Bees(a1, a2 + 2, b1, b2);
}
else { //上行
Bees(a1 + 1, a2, b1, b2);
Bees(a1, a2 + 2, b1, b2);
}
}
void ABee_main()
{
int a, b, a1, a2, b1, b2;
int i, j;
__int64 num[50] = { 0 };
printf("請輸入起/終點a/b:");
scanf("%d %d", &a, &b); //3 6 0-1 1-3
printf("請輸入解法1或2:");
scanf("%d", &i);
switch (i)
{
case 1:
printf("解法1:針對上/下列,各自遞推;\n");
/* 看成是二行X列的陣列 */
b1 = a % 2;a2 = a / 2; //1 1
a1 = b % 2;b2 = b / 2; //0 3
Bees(a1, a2, b1, b2);
printf("the num:%d\n", sum_bees);
break;
case 2:
printf("解法2:除了1和2,其餘數字都是由上個數字走過來或上上個數字走過來,故而累加即可;\n");
num[1] = 1;num[2] = 2;
for (j = 3;j <= b - a;j++) num[j] = num[j - 1] + num[j - 2];
printf("the num:%I64d\n", num[j - 1]);
break;
default:
printf("輸入有誤。");
break;
}
}
實現下面的虛擬碼。另外給定a, b, c,求w(a, b, c)的值。
function w(a, b, c):
if a <=0 or b <=0 or c <=0, then returns:1
if a >20or b >20or c >20, then returns: w(20,20,20)
if a < b and b < c, then returns: w(a, b, c-1)+ w(a, b-1, c-1)- w(a, b-1, c)
otherwise it returns: w(a-1, b, c)+ w(a-1, b-1, c)+ w(a-1, b, c-1)
問題在於如果直接計算,對於任意一個三元組(a, b, c),w(a, b, c)可能被計算多次。但對於固定的(a, b, c),w(a, b, c)其實是個固定的值,沒必要多次計算。所以我們建立一個三維陣列 num[21][21][21] ,在每次if判斷之前先查表,如果 num[a][b][c] 已儲存了計算結果,就直接取出來用,否則就進行之後的遞迴計算,並把結果存在 num[a][b][c] 裡。這樣對於任意(a, b, c)就只會計算一次值,此後再遇到就只是查表而已,單次查詢的複雜度降到O(1),總的複雜度為O(n^3),n為資料規模。這種思路學名【記憶化搜尋】。
/* Function Run Fun */
int runfun[21][21][21] = { 0 };
int FunctionRunFun(int a, int b, int c)
{
if (a <= 0 || b <= 0 || c <= 0) return 1;
else if (a > 20 || b > 20 || c > 20) {
if (runfun[20][20][20] != 0)
{
return runfun[20][20][20];
}
else
{
runfun[20][20][20] = FunctionRunFun(20, 20, 20);
return runfun[20][20][20];
}
}
else if (a < b&& b < c)
{
if (runfun[a][b][c] != 0)
{
return runfun[a][b][c];
}
else
{
runfun[a][b][c] = FunctionRunFun(a, b, c - 1) + FunctionRunFun(a, b - 1, c - 1) - FunctionRunFun(a, b - 1, c);
return runfun[a][b][c];
}
}
else
{
if (runfun[a][b][c] != 0)
{
return runfun[a][b][c];
}
else
{
runfun[a][b][c] = FunctionRunFun(a - 1, b, c) + FunctionRunFun(a - 1, b - 1, c) + FunctionRunFun(a - 1, b, c - 1) - FunctionRunFun(a - 1, b - 1, c - 1);
return runfun[a][b][c];
}
}
}
int main()
{
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
printf("%d\n", FunctionRunFun(a, b, c));
return 0;
}
飯卡
電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷餘額。如果購買一個商品之前,卡上的剩餘金額大於或等於5元,就一定可以購買成功(即使購買後卡上餘額為負),否則無法購買(即使金額足夠)。所以大家都希望儘量使卡上的餘額最少。
某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜的價格以及卡上的餘額,問最少可使卡上的餘額為多少。
【輸入格式】
多組資料。對於每組資料:
第一行為正整數n,表示菜的數量。n<=1000。
第二行包括n個正整數,表示每種菜的價格。價格不超過50。
第三行包括一個正整數m,表示卡上的餘額。m<=1000。
n=0表示資料結束。【輸出格式】
對於每組輸入,輸出一行,包含一個整數,表示卡上可能的最小余額。
【樣例輸入】
1 50 5 10 1 2 3 2 1 1 2 3 2 1 50 0
【樣例輸出】
-45 32
揹包問題。把可用餘額減去5,對菜價進行降序排序,從第二高價的菜品開始搜。
狀態轉移方程為 dp[ j ] = max(dp[ j ], dp[ j - v[ i ]] + v[ i ])。前者是不買菜,後者是買菜( j - v[ j ] 即買了菜後的餘額),此時已買的菜的總價值dp[ j ]就要加上此次購買的單價v[ j ]。兩者之間取價值最大的情況。
最後把買的菜的總價值加上最貴的菜的價值,就是此次購買的金額,則餘額也就可求了。
/* 飯卡 */
void MealCard()
{
int i, j, n, v[1024], money, dp[1024];//菜數、菜價格、餘額
printf("菜數:");
scanf("%d", &n);
printf("依次菜價:\n");
for (i = 0;i < n;i++) scanf("%d", &v[i]);
printf("餘額:");
scanf("%d", &money);
if (money < 5) printf("餘額不足!");
sort(v, v + n, greater<>()); //價格降序
memset(dp, 0, sizeof(dp)); //初始化陣列
for (i = 1;i < n;i++)
for (j = money - 5;j >= v[i];j--)
dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
printf("the balance :%d\n", money - dp[money - 5] - v[0]);
}
相關推薦
藍橋杯練習題(二)
n!的位數 將n!表示成10的次冪,即n!=10^M(10的M次方),則不小於M的最小整數就是 n!的位數,對該式兩邊取對數,有 M =log10^n! 由公式log(a*b)=loga+logb,可化為:M = log10^1+log10^2+log10^3.
Python練習題(基礎知識練習題(二))
strip() 哪些 字符 單行註釋 alt imp exe 列表 表格形式 1.執行Python腳本的兩種方式 (1).交互方式:啟動python解釋器,執行命令 (2).腳本方式:Python xxx.py 或者 chmod +x && ./xxx.p
Python練習題(二)
python練習題# 1.字符串最後一個單詞的長度 題目描述:計算字符串最後一個單詞的長度,單詞以空格隔開。 輸入描述: 一行字符串,非空,長度小於5000。輸出描述: 整數N,最後一個單詞的長度。示例1: 輸入:hello world 輸出:5# 2. 計算字符個數題目描述: 寫出一個程序,接受
Linux基礎練習題(二)
smo grub 用戶名 banner bash sre 開頭 boot .bashrc 系統版本: [root@centos67d1 ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [root@centos6
python學習筆記 day44 mysql 練習題(二)
1. 練習題二題目來自於:http://www.cnblogs.com/wangfengming/articles/7889786.html 這部分的習題 大致看了一下,沒有實際建立表來做,這裡選幾個比較有代表性的題大致說一下思路: 表的資訊如下: 24. 刪除工資重複的人員,保留年
2014年 藍橋杯決賽(Java)
國王的遺產 X國是個小國。國王K有6個兒子。在臨終前,K國王立下遺囑:國王的一批牛作為遺產要分給他的6個兒子。 其中,大兒子分1/4,二兒子1/5,三兒子1/6,.... 直到小兒子分1/9。 牛是活的,不能把一頭牛切開分。
信息安全練習題(二)
網絡 簽發證書 範圍 級別 相關 廣泛 ids 防禦 用戶操作 1. (D) 不屬於對稱加密算法。A. IDEAB. DESC. RC5D. RSA解析:IDEA、DES、RC5 都屬於對稱加密算法,RSA 屬於非對稱加密算法。 2. 如果發送方使用的加密密鑰和接收
MYSQL基礎上機練習題(二) 資料插入、修改、刪除
一、實驗目的: 資料插入、修改、刪除 資料表的複製 欄位分列 二、實驗內容: 對上一章所展示的表進行資料輸入、修改、刪除 上一章各表的欄位屬性 以下為Employees,Departments,Salary表中的內容 Employees表
MYSQL基礎上機練習題(二)對資料指定列查詢、條件查詢、查詢結果排序、聚集函式查詢、分組統計查詢
實驗目標:1.掌握指定列或全部列查詢2.掌握按條件查詢3.掌握對查詢結果排序4.掌握使用聚集函式的查詢5.掌握分組統計查詢一、請完成書中實驗7.1,並完成以下問題。1.查詢所有學生的姓名及其出生年份回答以下問題:SQL語句請截圖① 觀察查詢的資料,若年齡不為空是否能求出出生年
python學習--小練習題(二)
階段性總結2201802231.求0—7所能組成的奇數個數。程式分析:組成1位數是4個。組成2位數是7*4個。組成3位數是7*8*4個。組成4位數是7*8*8*4個。......try: number = int(raw_input("please input a numbe
機器學習練習題(二)
從牛客網找來得題目,解析是題目下的高贊答案。 1.下面有關分類演算法的準確率,召回率,F1 值的描述,錯誤的是? a.準確率是檢索出相關文件數與檢索出的文件總數的比率,衡量的是檢索系統的查準率 b.召回率是指檢索出的相關文件數和文件庫中所有的相關文件數的比率,衡量的是檢索系
藍橋杯練習(vip) 報時助手
/*問題描述 給定當前的時間,請用英文的讀法將它讀出來。 時間用時h和分m表示,在英文的讀法中,讀一個時間的方法是: 如果m為0,則將時讀出來,然後加上“o'clock”,如3:00讀作“three o'clock”。 如果m不為0,則將時讀出來,然後將分讀
第六屆藍橋杯題目(java)-奇妙的數字
【題目描述】 《奇妙的數字》小明發現了一個奇妙的數字。它的平方和立方正好把0~9的10個數字每個用且只用了一次。你能猜出這個數字是多少嗎? 請填寫該數字,不要填寫任何多餘的內容。 【題目分析】 1)利用Java 的set集合,集合中的數字不可以重複; 2)在while迴圈中
藍橋杯練習系統試題集(二)--基礎練習(含C/C++答案)
藍橋杯練習系統試題集(二)–基礎練習(含C/C++答案) 1 基礎練習 閏年判斷 時間限制:1.0s 記憶體限制:256.0MB 提交此題 錦囊1 錦囊2 問題描述 給定一個年份,判斷這一年是不是閏年。 當以下情況之一滿足時
藍橋杯練習題:機器人(java)
package lanqiaobei; import java.util.HashMap; import java.util.Scanner; /* 蒜頭君收到了一份禮物,是一個最新版的機器人。這個機器人有4種指令: 1. forward x,前進 x 米。 2. back x,先向後轉,然後前
藍橋杯練習題---完美的代價(基於貪心演算法)
有一段時間沒有用c++寫過程式了,偶爾心血來潮刷兩道水題,沒想到居然被一道題卡住了。。。。很難受emmmm寫出來給大家分享下,覺得這道題挺精妙的,有值得學習的地方(大神可忽略)題目如下:問題描述 迴文串,是一種特殊的字串,它從左往右讀和從右往左讀是一樣的。小龍龍認為迴文串才
2017第八屆藍橋杯決賽(B組)2.磁磚樣式
利用 分享 部分 span 裝飾 mage 整數 bool png 磁磚樣式 小明家的一面裝飾墻原來是 310 的小方格。 現在手頭有一批剛好能蓋住2個小方格的長方形瓷磚。 瓷磚只有兩種顏色:黃色和橙色。 小明想知道,對於這麽簡陋的原料,可以貼出多少種不同的花樣來。 小明有
2017第八屆藍橋杯決賽(B組)4.發現環
之間 bound 維護 順序 ins 兩個 class () clas 描述 小明的實驗室有N臺電腦,編號1~N。原本這N臺電腦之間有N-1條數據鏈接相連,恰好構成一個樹形網絡。在樹形網絡上,任意兩臺電腦之間有唯一的路徑相連。 不過在最近一次維護網絡時,管理員誤操作使得某兩
(二)Mysql面試筆試練習題
最常用聚合函式: AVG() 平均值 COUNT() 計數 MAX() 最大值 MIN() 最小值 SUM() 求和 6、查詢平均成績大於60分的同學的學號和平均成績 SELECT s.student_id,AVG(s.score) FROM score s GROUP BY s.stu
達觀杯_構建模型(二)邏輯迴歸
特徵:tfidf(word+article) """ 1.特徵:tfidf(word+article) 2.模型:lr 3.引數:C=120 """ import pandas as pd import pickle from sklearn.linear_m