2017藍橋杯C++A組題解集合
總結:藍橋杯的題目大多數都是暴利或者dfs、bfs解出來的,注意往這上面思考
下面是賽題的連結:https://wenku.baidu.com/view/951dab772a160b4e767f5acfa1c7aa00b52a9d2d.html
然後就是部分試題的答案,有些轉載的,僅供參考
一、迷宮
四、方格分割
/*
仔細觀察樣例資料可以發現,要滿足題目所需要求,只需要剪下的線關於圖案的中點中心對稱。
那麼我們可以將格子格子之間接壤的看作邊,邊與邊相交的看作點。則從(3,3)點出發,
找一條邊到達圖案的外圈,不過值得注意的是,從(3,3)出發的是看錯兩個人出發,兩個人的線路一直是對稱。
所以dfs中標記的時候要一步標記兩個。最後的結果要除以4,因為題目中說要旋轉對稱的是同一種。
*/
#include<bits/stdc++.h>
using namespace std;
int visited[10][10];
int ans=0;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
void dfs(int x,int y)
{
if(x==0||y==0||x==6||y==6)
{
ans++;
return;
}
for(int i=0;i<4;i++)
{
int nx=x+dir[i][0];
int ny=y+dir[i][1];
if(visited[nx][ny])
continue;
visited[nx][ny]=1;
visited[6-nx][6-ny]=1;
dfs(nx,ny);
visited[nx][ny]=0;
visited[6-nx][6-ny]=0;
}
}
int main()
{
memset(visited,0,sizeof visited);
visited[3][3]=1;
dfs(3,3);
printf("%d %d\n",ans,ans/4);
}
五、字母組串
f(a-1,b,c,n-1)+f(a,b-1,c,n-1)+f(a,b,c-1,n-1)
六、最大公共子串
a[i-1][j-1]+1
七、正則問題
#include <iostream>
#include<algorithm>
using namespace std;
string str;
int pos, len;
int dfs()
{
int xnum = 0, res = 0;
while (pos < len) {
if (str[pos] == '(') {
pos++;
xnum += dfs();
}
else if (str[pos] == ')') {
pos++;
break;
}
else if (str[pos] == '|') {
pos++;
res = max(xnum, res);
xnum = 0;
}
else {
pos++;
xnum++;
}
}
res = max(xnum, res);
return res;
}
int main()
{
cin >> str;
int ans = 0;
len = str.length(), pos = 0;
ans = dfs();
cout << ans << endl;
return 0;
}
八、包子湊數
這道題用到了數論的知識:本題要判斷能不能湊出c個包子就相當於判斷ax+by=c這個方程的是否有解,根據數論知識我們知道gcd(a,b)如果不等於1,那麼湊不出來的c就有無窮多個,程式碼中的求gcd的函式應該熟記,然後else裡面的for迴圈就是動態規劃求出所有引數能湊出的包子數
#include <cstdio>
using namespace std;
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a%b);
}
int unit[110], n;
const int N = 10010;
bool sign[N];
int main(){
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &unit[i]);
int g = unit[0];
for (int i = 1; i < n; i++)
g = gcd(g, unit[i]);
if (g != 1){
printf("INF\n");
}
else{
sign[0] = true;
for (int i = 0; i < n; i++){
for (int j = 0; j + unit[i] < N; j++)
if (sign[j])
sign[j + unit[i]] = true;
}
int count = 0;
for (int i = 0; i < N - 1; i++){
if (sign[i] == false)
count++;
}
printf("%d\n", count);
}
return 0;
}
九、分巧克力
#include <cstdio>
using namespace std;
int n, k, length[100010], wide[100010];
bool chocolate(int x) //判斷正方形邊長x時能不能切出大於等於K塊
{
int num = 0, a, b, i;
for (i = 0; i<n; i++) //n塊巧克力一共能切出num塊分給小朋友們
{
a = length[i] / x;
b = wide[i] / x;
num += a*b;
}
if (num >= k)
return true;
return false;
}
int main()
{
int i, low, high;
while (scanf("%d%d", &n, &k) != EOF)
{
low = 1;
high = 100001;
for (i = 0; i<n; i++)
scanf("%d%d", &length[i], &wide[i]);
while (low<high-1) //二分搜尋找出正方形巧克力邊長的最大值
{
int mid = (low + high) / 2;
if (!chocolate(mid))
high = mid;
else
low = mid;
}
printf("%d\n", low);
}
return 0;
}