寫在最前面:
本文中會出現大量的請查閱.請自學什麼的,不是我不講,本文是面向算法初學者和藍橋杯的文章,如果真的想看進階算法的也不會來看這些題目,所以不要介意,我這裏就算是拋磚引玉了,大佬勿噴,ACMEer繞道哈哈哈哈。
1.楊輝三角形
問題描述
楊輝三角形又稱Pascal三角形,它的第i+1行是(a+b)i的展開式的係數。
它的一個重要性質是:三角形中的每個數字等於它兩肩上的數字相加。
下面給出了楊輝三角形的前4行:
1
1 1
1 2 1
1 3 3 1
給出n,輸出它的前n行。
輸入格式
輸入包含一個數n。
輸出格式
輸出楊輝三角形的前n行。每一行從這一行的第一個數開始依次輸出,中間使用一個空格分隔。請不要在前面輸出多餘的空格。
樣例輸入
4
樣例輸出
1
1 1
1 2 1
1 3 3 1
數據規模與約定
1 <= n <= 34。
楊輝三角形入門的話就是考察代碼編寫,是個模擬題目,當數據量達到一定程度之後是組合數問題,可以使用盧卡斯定理,這裏是入門,暫且不提,有興趣可以去我博客數論查找!
#include <bits/stdc++.h>
using namespace std;
int s[1000], a[1000];
void print(int source[], int ans[], int now, int target) //狀態轉移
{
for (int i = 0; i < now; i++)
{
i == 0 ? ans[i] = 1 : ans[i] = source[i] + source[i - 1];
cout << ans[i] << "\t";
}
puts("");
if (now == target)
return;
print(ans, source, now + 1, target);
}
int main()
{
int n;
cin >> n;
print(s, a, 1, n);
}
2.字符串比較
問題描述
給定兩個僅由大寫字母或小寫字母組成的字符串(長度介於1到10之間),它們之間的關係是以下4中情況之一:
1:兩個字符串長度不等。比如 Beijing 和 Hebei
2:兩個字符串不僅長度相等,而且相應位置上的字符完全一致(區分大小寫),比如 Beijing 和 Beijing
3:兩個字符串長度相等,相應位置上的字符僅在不區分大小寫的前提下才能達到完全一致(也就是說,它並不滿足情況2)。比如 beijing 和 BEIjing
4:兩個字符串長度相等,但是即使是不區分大小寫也不能使這兩個字符串一致。比如 Beijing 和 Nanjing
編程判斷輸入的兩個字符串之間的關係屬於這四類中的哪一類,給出所屬的類的編號。
輸入格式
包括兩行,每行都是一個字符串
輸出格式
僅有一個數字,表明這兩個字符串的關係編號
樣例輸入
BEIjing
beiJing
樣例輸出
3
直接可以討論用c++的string即可,相關的string操作:1.可以判等== 2.可以比較字典序 < 或 > 3.reserve反轉 4.length()判斷長度
#include <bits/stdc++.h>
using namespace std;
int compare(string s1,string s2)
{
if(s1.length()==s2.length())
{
if(s1==s2)return 2;
for(int i=0;i<s2.length();i++)
{
if(toupper(s1[i])!=toupper(s2[i])) return 4;
}
return 3;
}
else return 1;
}
int main()
{
string s1,s2;
cin>>s1>>s2;
cout<<compare(s1,s2);
}
3.N皇后問題Plus
問題描述
給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。
輸入格式
輸入的第一行爲一個整數n,表示棋盤的大小。
接下來n行,每行n個0或1的整數,如果一個整數爲1,表示對應的位置可以放皇后,如果一個整數爲0,表示對應的位置不可以放皇后。
輸出格式
輸出一個整數,表示總共有多少种放法。
樣例輸入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
樣例輸出
2
樣例輸入
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
樣例輸出
0
解析
N皇后問題,是一類搜索問題,這裏我們使用4個數組來保證米字的形狀沒有皇后,斜線的保存我們要發現一條左斜線的橫座標減縱座標是相同的,同一右斜線上的點橫縱座標相加的值相同,由此我們可以推理出以下搜索策略
#include <bits/stdc++.h>
using namespace std;
int mp[10][10];
int hen[10], shu[10], zuo[100], you[100];
int ans = 0;
void js(int len, int cen)
{
if (cen == len)
{
ans++;
return;
}
// puts("--------------------------------------------------------\n");
// for (int i = 0; i < len; i++)
// {
// for (int j = 0; j < len; j++)
// {
// cout<< mp[i][j]<<" ";
// }
// puts("");
// }
for (int i = 0; i < len; i++)
{
if (hen[i] == 0 && shu[i] == 0 && zuo[(cen + i) / 2] == 0 && you[cen - i + len] == 0 && mp[cen][i])
{
mp[cen][i] = 0;
hen[i] = shu[i] = zuo[(cen + i + 1) / 2] = you[cen - i + len] = 1;
js(len, cen + 1);
mp[cen][i] = 1;
hen[i] = shu[i] = zuo[(cen + i + 1) / 2] = you[cen - i + len] = 0;
}
}
return;
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
cin >> mp[i][j];
}
js(n, 0);
cout << ans << endl;
}
4.導彈攔截
問題描述
某國爲了防禦敵國的導彈襲擊,發展出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的導彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的導彈。
輸入導彈依次飛來的高度(雷達給出的高度數據是不大於30000的正整數),計算這套系統最多能攔截多少導彈,如果要攔截所有導彈最少要配備多少套這種導彈攔截系統。
輸入格式
一行,爲導彈依次飛來的高度
輸出格式
兩行,分別是最多能攔截的導彈數與要攔截所有導彈最少要配備的系統數
樣例輸入
389 207 155 300 299 170 158 65
樣例輸出
6
2
這是一類動態規劃問題,LIS問題。
第一問是求一個數列的最長下降子序列,第二問則是最長的非嚴格上升子序列(如3 3 2 1,可以相等)因爲最長上升子序列的每一個高度都需要一套攔截系統,彼此獨立。
#include <bits/stdc++.h>
using namespace std;
int h[1000];
int dp[1000][2];
map<int,int> cou;
pair<int,int> Lis(int a[],int len)
{
int ans=0,cnt=0;
for(int i=0;i<len;i++)
{
for(int j=0;j<i;j++)
{
if(h[j]<h[i]) dp[i][0]=max(dp[i][0],dp[j][0]+1);
else dp[i][1]=max(dp[i][1],dp[j][1]+1);
ans=max(ans,dp[i][0]);
cnt=max(cnt,dp[i][1]);
}
}
return make_pair(ans+1,cnt+1);
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> h[i];
auto answ=Lis(h,n);
cout<<answ.first<<" "<<answ.second <<endl;
}
5.Fibonacci數列
問題描述
Fibonacci數列的遞推公式爲:Fn=Fn-1+Fn-2,其中F1=F2=1。
當n比較大時,Fn也非常大,現在我們想知道,Fn除以10007的餘數是多少。
輸入格式
輸入包含一個整數n。
輸出格式
輸出一行,包含一個整數,表示Fn除以10007的餘數。
說明:在本題中,答案是要求Fn除以10007的餘數,因此我們只要能算出這個餘數即可,而不需要先計算出Fn的準確值,再將計算的結果除以10007取餘數,直接計算餘數往往比先算出原數再取餘簡單。
樣例輸入
10
樣例輸出
55
樣例輸入
22
樣例輸出
7704
數據規模與約定
1 <= n <= 1,000,000。
因爲是入門,藍橋杯也考不了這麼難,這裏寫遞推。如果有興趣進階的話,可以研究下,矩陣快速冪,和母函數的做法,我博客裏應該都有!
#include <bits/stdc++.h>
using namespace std;
const int MOD=10007;
int f[100000];
int init(int n)
{
f[1]=f[2]=1;
for(int i=3;i<=n;i++)
f[i]=f[i-1]+f[i-2]%MOD;
}
int main()
{
int n;
cin>>n;
init(n);
cout<<f[n]<<endl;
}
6.校門外的樹
問題描述
某校大門外長度爲L的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1米。我們可以把馬路看成一個數軸,馬路的一端在數軸0的位置,另一端在L的位置;數 軸上的每個整數點,即0,1,2,……,L,都種有一棵樹。
由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已 知任一區域的起始點和終止點的座標都是整數,區域之間可能有重合的部分。現在要把這些區域中的樹(包括區域端點處的兩棵樹)移走。你的任務是計算將這些樹 都移走後,馬路上還有多少棵樹。
輸入格式
輸入文件的第一行有兩個整數L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表馬路的長度,M代表區域的數目,L和M之間用一個空格隔開。接下來的M行每行包含兩個不同的整數,用一個空格隔開,表示一個區域的起始點 和終止點的座標。
輸出格式
輸出文件包括一行,這一行只包含一個整數,表示馬路上剩餘的樹的數目。
樣例輸入
500 3
150 300
100 200
470 471
樣例輸出
298
數據規模和約定
對於20%的數據,區域之間沒有重合的部分;
對於其它的數據,區域之間有重合的情況。
這道題很簡單是簽到題,就是考察的模擬,會不會處理區間重疊情況,這道題的進階做法是差分,有興趣的可以查閱,我們這裏只是藍橋杯和入門
#include <bits/stdc++.h>
using namespace std;
int a[1000000];
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
int l,r;
cin>>l>>r;
for(int j=l;j<=r;j++)
{
a[j]=-1;
}
}
int ans=0;
for(int i=0;i<=n;i++)
if(a[j]==0) ans++;
cout<<ans<<endl;
}
7.奪寶奇兵
算法提高 奪寶奇兵
時間限制:1.0s 內存限制:512.0MB
[題目描述]
在一座山上,有很多很多珠寶,它們散落在山底通往山頂的每條道路上,不同道路上的珠寶的數目也各不相同.下圖爲一張藏寶地圖:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
”奪寶奇兵”從山下出發,到達山頂,如何選路才能得到最多的珠寶呢?在上圖所示例子中,按照5->7->8->3->7的順序,將得到最大值30
[輸入]
第一行正整數N(100>=N>1),表示山的高度
接下來有N行非負整數,第i行有i個整數(1<=i<=N),表示山的第i層上從左到右每條路上的珠寶數目
[輸出]
一個整數,表示從山底到山頂的所能得到的珠寶的最大數目.
[樣例輸入]
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
[樣例輸出]
30
經典DP算法,可以自下而上也可以從上向下,每次只保留最優的選擇方案,狀態轉移方程爲:
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + mountain[i][j];
#include <bits/stdc++.h>
using namespace std;
int mountain[MAXN][MAXN];
int dp[MAXN + 1][MAXN + 1];
int main()
{
cin>>n;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j <= i; ++j)
cin>>mountain[i][j];
}
for (int i = N - 1; i >= 0; --i)
{
for (int j = 0; j <= i; ++j)
{
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + mountain[i][j];
}
}
cout<<dp[0][0]<<endl;
}
8.質因數分解
基礎練習 分解質因數
時間限制:1.0s 內存限制:512.0MB
問題描述
求出區間[a,b]中所有整數的質因數分解。
輸入格式
輸入兩個整數a,b。
輸出格式
每行輸出一個數的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是從小到大的)(具體可看樣例)
樣例輸入
3 10
樣例輸出
3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5
提示
先篩出所有素數,然後再分解。
數據規模和約定
2<=a<=b<=10000
因爲是對區間進行分解,那麼質因數將會用到很多次,我們不能每一次都進行試除法,所以預先達標保留,我這裏只用了一次試除法,每次對求出小於右端點的所有質因子,這裏用了一個小優化,一個數的一對因子不可能都大於他開根號,對於質數的篩法有埃式篩法和線性篩法我博客裏也有可以去看,寫到這裏真的用不着,時間給的很充足。
#include <bits/stdc++.h>
using namespace std;
int prime[10000], cnt = 0;
void init(int n)
{
for (int i = 2; i < n; i++)
{
int flag = 0;
for (int j = 2; j * j <= i; j++)
{
if (i % j == 0)
{
flag = 1;
break;
}
}
if (flag == 1)
continue;
else
{
prime[++cnt] = i;
}
}
}
void fj(int n)
{
cout << n << "=";
int flag = 0;
for (int i = 1; prime[i] <= n; i++)
{
while (n % prime[i] == 0)
{
if (!flag)
{
flag = 1;
}
else
cout << "*";
cout << prime[i];
n /= prime[i];
}
}
puts("");
}
int main()
{
int l, r;
cin >> l >> r;
init(r);
for (int i = l; i <= r; i++)
{
fj(i);
}
}
寫在最後:
我叫風骨散人,名字的意思是我多想可以不低頭的自由生活
,可現實卻不是這樣。家境貧寒,總得向這個世界低頭,所以我一直在奮鬥,想改變我的命運
給親人好的生活,希望同樣被生活綁架的你
可以通過自己的努力改變現狀,深知成年人的世界裏沒有容易二字。目前是一名在校大學生,預計考研,熱愛編程,熱愛技術,喜歡分享,知識無界,希望我的分享可以幫到你!
如果有什麼想看的,可以私信我,如果在能力範圍內,我會發布相應的博文!
感謝大家的閱讀!😘你的點贊、收藏、關注是對我最大的鼓勵!