蓝桥杯2019c语言b组试题,2020年7月B组C++蓝桥杯真题试水
哇!剛剛突然發(fā)現(xiàn)我的那篇擴(kuò)展歐幾里得達(dá)到了500+的閱讀量,開森森~ 看起來努力就是有回報(bào)的嘛!用心寫的文章和不用心寫的文章相信廣大程序員萌都一眼看得出來撒~
快樂!你們的關(guān)注和點(diǎn)贊是我最大的動(dòng)力嗷!┗|`O′|┛
好了,閑話不多說~ 正片開始!
A.跑步訓(xùn)練
這個(gè)題個(gè)人不建議寫程序,直接手算就好了,但是要注意的是,每一輪-600然后+300,就相當(dāng)于-300,但是!一定要記得這-300的時(shí)間是120s,而不是60s,手算黨千萬要小心!檢查檢查再檢查,這個(gè)分丟得相當(dāng)不值得。
結(jié)果:3880
B.紀(jì)念日
日期題目年年有,一點(diǎn)都不稀奇~關(guān)鍵在于快速A,聽說C++算日期很麻煩,誰要咱也不是Java選手呢,害,魚和熊掌⑧可兼得嘛,祭上大殺器——計(jì)算器!
結(jié)果:52038720
C.合并檢測(cè)
這個(gè)題,數(shù)學(xué)功底相當(dāng)強(qiáng) 懶得寫程序的我,直接手算!
結(jié)果:10
D.REPEAT程序
先說好啊,這玩意不是按照樣例算的,實(shí)戰(zhàn)的時(shí)候人家是給了數(shù)據(jù)的,是一個(gè)txt文件,那玩意長(zhǎng)的,保證你放棄硬寫出這些個(gè)循環(huán)的想法。
我重新梳理了一遍帶佬的思路,然后附上了詳細(xì)注釋`#include
using namespace std;
const int N = 1e5 + 10;
char str[N];
int a[N], b[N];//a用來存放當(dāng)前行層的縮進(jìn)格數(shù),b用來存放當(dāng)前層的循環(huán)次數(shù)
int main(int argc, char const *argv[])
{
int pos = 0, p = 0, w = 1, ans = 0;//pos存第幾層循環(huán),p存每行前面的空格數(shù),w是總的循環(huán)數(shù),ans存結(jié)果
a[0] = -1, b[0] = 1;
freopen("prog.txt","r",stdin);//就是將標(biāo)準(zhǔn)輸入流重定向到這個(gè)txt文件中,
//從文件中獲取輸入
gets(str);//首行的“A=0”不需要
while(gets(str)){
int len = strlen(str);
p = 0;//每次p都要?dú)w零啊
while(str[p] == ' ') p++;
while(p <= a[pos]) w /= b[pos--];//說明退出了最近的那一層
if(str[len - 1] == ':'){//是REPEAT語句
int k = str[len - 2] - '0';//當(dāng)前循環(huán)重復(fù)的次數(shù)
w *= k;
pos ++;//來到新的一層
a[pos] = p, b[pos] = k;
}else {//不是循環(huán)語句
int k = str[len - 1] - '0';//要加上的數(shù)
ans += w * k;
}
}
cout<
return 0;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
* 26
* 27
* 28
* 29
* 30
* 31
結(jié)果:241830
E.矩陣
這題很容易讓人想起我們之前做過的那一道DP+打表的題目,有人說DP本質(zhì)就是打表,我覺得可以這么說,起碼以目前我不太高深的實(shí)力,可以這么理解。
首先我們自己列出小數(shù)據(jù)表格,然后根據(jù)列出的表格找規(guī)律并且寫代碼。
這樣的填表莫名讓我想起了小學(xué)課本上的那個(gè)找國王要米的人,在棋盤上堆米直到堆成山。。
其實(shí)自己在草稿紙上畫一畫很容易發(fā)現(xiàn)規(guī)律——也就是我們要的遞推式。
代碼就很好寫了~~`#include
using namespace std;
const int N = 2025;
int dp[N][N];
int main(int argc, char const *argv[])
{
dp[1][1] = 1;//1必然在首格
for (int i = 2; i <= 2020; ++i)
{
for (int j = 1; j <= i; ++j)//在第一行放j個(gè)
{
dp[i][j] += dp[i - 1][j - 1];
if(2 * j >= i) dp[i][j] += dp[i - 1][j];//如果第一行的數(shù)目>=第二行,那么就還可以加上上方那個(gè)
dp[i][j] %= 2020;//可能數(shù)很大
}
}
printf("%dn", dp[2020][1010]);//注意是第1010列
return 0;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
F.整除序列
苦等了這么久終于來了一道簽到題!/(ㄒoㄒ)/~~
藍(lán)橋是不是變🚹了嗚嗚嗚`#include
using namespace std;
typedef long long ll;
ll n;
int main(int argc, char const *argv[])
{
scanf("%ld", &n);
while(n >= 1){
printf("%ld", n);
if(n != 1) printf(" ");
else printf("n");
n = (int) n >> 1;
}
return 0;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
G.解碼
簽到×2!果然不會(huì)讓咱們太難看哈~
我呵呵呵我又不審題!我把字母l看成了1,哭暈。。我難看了,對(duì)八七!我反省!我以后一定好好審題!`// #include
// using namespace std;
// const int MAXN = 110;
// char str[MAXN];
// int main(int argc, char const *argv[])
// {
// scanf("%s",str);
// int len = strlen(str);
// for (int i = 0; i < len; )
// {
// char ch;
// int num = 0, digit = 0;
// if((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')){
// ch = str[i];
// }
// while(str[++i] >= '0' && str[i] <= '9'){
// digit += str[i] - '0';
// num += digit;
// digit *= 10;
// }
// for (int j = 0; j < num; ++j) putchar(ch);
// }
// printf("n");
// return 0;
// }
#include
using namespace std;
const int MAXN = 110;
char s[MAXN];
int main() {
scanf("%s", s);
for (int i = 0; s[i]; i++) {
if (s[i] >= 'a' && s[i] <= 'z') {
putchar(s[i]);
} else if (s[i] >= 'A' && s[i] <= 'Z') {
putchar(s[i]);
} else {
int k = s[i] - '0' - 1;
while (k--) putchar(s[i - 1]);
}
}
puts("");
return 0;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
* 26
* 27
* 28
* 29
* 30
* 31
* 32
* 33
* 34
* 35
* 36
* 37
* 38
* 39
* 40
* 41
* 42
* 43
* 44
* 45
* 46
H.走方格
雖然興奮,切記還是不能大意~`#include
using namespace std;
const int N = 35;
int dp[N][N];
int main(int argc, char const *argv[])
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if(i == 1 && j == 1){ //只需要一個(gè)1
dp[i][j] = 1;
continue;
}
if(i & 1 || j & 1) //只要有一個(gè)不是2的倍數(shù)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
printf("%dn", dp[n][m]);
return 0;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
I.整數(shù)拼接
這題,確實(shí)沒思路,要是暴力肯定炸,于是瞪著帶佬沒有注釋的代碼看了一個(gè)小時(shí),終于。。懂了,現(xiàn)在給親愛的讀者朋友們奉上注釋~`#include
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int cnt[10][N];
int a[N];
int ans;
int get_length(int x){ //得到一個(gè)整數(shù)的長(zhǎng)度(利用傳形參不變實(shí)際值)
int length = 0;
while(x){
x /= 10;
length++;
}
return length;
}
int main(int argc, char const *argv[])
{
int n, m;
scanf("%d%d", &n, &m);
int ans = 0;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i)
{
int len = get_length(a[i]);
int left = (m - a[i] % m) % m; //這個(gè)left和a[i]%m是關(guān)于m互余的
ans += cnt[len][left];//看看前面有沒有契合的拼接對(duì)象
int p = 10;//十位起步
for (int j = 1; j <= 9; ++j)
{
cnt[j][1ll * p * a[i] % m] ++;//這個(gè)數(shù)的另一半是j位,這個(gè)數(shù)就是(j+1)位,不然無法拼接
p *= 10;
}
}
memset(cnt, 0, sizeof(cnt));//記得清空
for (int i = n; i >= 1; --i)//反著跑一遍
{
int len = get_length(a[i]);
int left = (m - a[i] % m) % m;
ans += cnt[len][left];//看看后面有沒有契合的拼接對(duì)象
int p = 10;//十位起步
for (int j = 1; j <= 9; ++j)
{
cnt[j][1ll * p * a[i] % m] ++;//這個(gè)數(shù)的另一半是j位,這個(gè)數(shù)就是(j+1)位,不然無法拼接
p *= 10;
}
}
printf("%dn", ans);
return 0;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
* 26
* 27
* 28
* 29
* 30
* 31
* 32
* 33
* 34
* 35
* 36
* 37
* 38
* 39
* 40
* 41
* 42
* 43
* 44
* 45
* 46
* 47
* 48
* 49
* 50
* 51
* 52
為什么(m-x%m)和x%m是契合的呢?
我們來研究一個(gè)案例就清楚了——
45為什么可以整除3?
因?yàn)?0%3=1(這一部分余三多一),而3-5%3也=1(這一部分余三少一),剛剛好,一拍即合!加起來就可以整除3。這也就是ans += cntlen的理由。
J.網(wǎng)絡(luò)分析
最后一題拖了三天了QWQ,效率太低了(廢物哇的一聲哭出來)
這題,不是裸的并查集,注意標(biāo)黃部分。
每次新的結(jié)點(diǎn)加入之后,之前集合中的點(diǎn)加上的值是不能算在新人頭上的,洗澡的時(shí)候想到了,每次新人加入的時(shí)候,就問問自己的父親現(xiàn)在手上有多少值,然后自己的結(jié)點(diǎn)就要減去前人積累(也就是加入的時(shí)候父親的值)的值,最后在輸出的時(shí)候檢查是否是根結(jié)點(diǎn),如果不是就要加上父親的值,等于新人加入之后的值之和。
本來想的是每個(gè)點(diǎn)都標(biāo)記前人的值,后來借鑒了帶佬的思路,每次在merge的時(shí)候減去根結(jié)點(diǎn)的值,然后再在最后加回來,就是加入之后的值,還是覺得這樣比較簡(jiǎn)單。#include
using namespace std;
typedef long long ll;
const int N = 1e4 + 10;
int father[N];
ll ans[N];
void init(int x){
for (int i = 1; i <= x; ++i)
father[i] = i;
}
int find(int x){
int a = x;
while(x != father[x]) x = father[x];//x抵達(dá)根節(jié)點(diǎn)
while(a != father[a]){//路徑壓縮
father[a] = x;
a = father[a];
}
return x;
}
void merge(int x, int y){
x = find(x), y = find(y);
if(x != y) {
father[x] = y; //x的粑粑是y
ans[x] -= ans[y]; //之前的別人的就要減掉,只算加入之后的【關(guān)鍵一步】
}
}
int main(int argc, char const *argv[])
{
int n, m, flag;
scanf("%d%d", &n, &m);
init(n);
while(m--){
scanf("%d", &flag);
if(flag == 1){
int a, b; scanf("%d%d",&a, &b);
merge(a, b);
}else {
int p, t; scanf("%d%d",&p, &t);
int fa = find(p);
ans[fa] += t;
}
}
for (int i = 1; i <= n; ++i)
{
ll res = ans[i];
int fa = find(i);
if(i != fa) res += ans[fa];
printf("%lld%c", res, " n"[i == n]);//最后輸出換行的方法,學(xué)習(xí)!
}
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的蓝桥杯2019c语言b组试题,2020年7月B组C++蓝桥杯真题试水的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【设计模式】单例模式 Singleton
- 下一篇: OC_KVC与KVO简单介绍