要打国赛了,赶紧先抱一下佛脚。
蓝桥杯刷题汇集
2021省赛 c++ A
2020蓝桥国赛c++ A
2020蓝桥国赛 c++ B(部分)
推荐阅读:
题目来源: 蓝桥杯厉届真题 https://www.lanqiao.cn/courses/2786
这篇是2019蓝桥杯国赛c++ A组, 看到有知乎大佬说做了第一道填空(5分)和1.5道大题就国二了…难度可想而知… 如何评价2019年第十届蓝桥杯国赛?(知乎)
思路: 考虑竖直,水平,左上到右下, 左下到右上,右上到左下五个方向(按题目意思,左下到右上,右上到左下是不一样的) 不建议用这个思路真的,后面有更简洁的。
#include
using namespace std;
const int MAXN = 1005;
int ans = 0;
string s[35];
// 计算 t 这个字符串有多少个三升序列
int cal(string t, int len) {
int cnt = 0;
// 小于3的长度的字符串当然没有啦(对角线有可能小于3,看下循环就明白了)
if (len < 3)
return 0;
for (int i = 0; i < len - 2; i++)
for (int j = i + 1; j < len - 1; j++)
for (int k = j + 1; k < len; k++)
if (t[i] < t[j] && t[j] < t[k])
cnt++;
return cnt;
}
bool check(int x, int y) {
return x >= 0 && x < 30 && y >= 0 && y < 50;
}
void solve() {
char temp[85];
// 竖直方向
for (int i = 0; i < 30; i++) {
int j = 0;
for (; j < 50; j++)
temp[j] = s[i][j];
ans += cal(temp, j);
}
// 水平方向
for (int i = 0; i < 50; i++) {
int j = 0;
for (; j < 30; j++)
temp[j] = s[j][i];
ans += cal(temp, j);
}
// 45度
// 左上->右下, 右上半部分
for (int begin = 49; begin >= 0; begin--) {
int pos = 0, x = 0, y = begin;
for (; check(x, y); x++, y++, pos++)
temp[pos] = s[x][y];
ans += cal(temp, pos);
}
// 左上 -> 右下, 左下半部分
for (int begin = 1; begin < 30; begin++) {
int pos = 0, x = begin, y = 0;
for (; check(x, y); x++, y++, pos++)
temp[pos] = s[x][y];
ans += cal(temp, pos);
}
//右上到左下, 左上半部分
for (int begin = 49; begin >= 0; begin--) {
int pos = 0, x = 0, y = begin;
for (; check(x, y); x++, y--, pos++)
temp[pos] = s[x][y];
ans += cal(temp, pos);
}
//右上到左下, 右下半部分
for (int begin = 1; begin < 30; begin++) {
int pos = 0, x = begin, y = 49;
for (; check(x, y); x++, y--, pos++)
temp[pos] = s[x][y];
ans += cal(temp, pos);
}
//左下->右上, 题目说和右上->左下不同, 左上半部分
for (int begin = 0; begin < 30; begin++) {
int pos = 0, x = begin, y = 0;
for (; check(x, y); x--, y++, pos++)
temp[pos] = s[x][y];
ans += cal(temp, pos);
}
//左下->右上, 题目说和右上->左下不同, 右下半部分
for (int begin = 1; begin < 50; begin++) {
int pos = 0, x = 29, y = begin;
for (; check(x, y); x--, y++, pos++)
temp[pos] = s[x][y];
ans += cal(temp, pos);
}
}
int main() {
for (int i = 0; i < 30; i++)
getline(cin, s[i]);
solve();
cout << ans << endl;
}
答案: 180414
题目所求:
VLPWJVVNNZSWFGHSFRBCOIJTPYNEURPIGKQGPSXUGNELGRVZAG
SDLLOVGRTWEYZKKXNKIRWGZWXWRHKXFASATDWZAPZRNHTNNGQF
ZGUGXVQDQAEAHOQEADMWWXFBXECKAVIGPTKTTQFWSWPKRPSMGA
BDGMGYHAOPPRRHKYZCMFZEDELCALTBSWNTAODXYVHQNDASUFRL
YVYWQZUTEPFSFXLTZBMBQETXGXFUEBHGMJKBPNIHMYOELYZIKH
ZYZHSLTCGNANNXTUJGBYKUOJMGOGRDPKEUGVHNZJZHDUNRERBU
XFPTZKTPVQPJEMBHNTUBSMIYEGXNWQSBZMHMDRZZMJPZQTCWLR
ZNXOKBITTPSHEXWHZXFLWEMPZTBVNKNYSHCIQRIKQHFRAYWOPG
MHJKFYYBQSDPOVJICWWGGCOZSBGLSOXOFDAADZYEOBKDDTMQPA
VIDPIGELBYMEVQLASLQRUKMXSEWGHRSFVXOMHSJWWXHIBCGVIF
GWRFRFLHAMYWYZOIQODBIHHRIIMWJWJGYPFAHZZWJKRGOISUJC
EKQKKPNEYCBWOQHTYFHHQZRLFNDOVXTWASSQWXKBIVTKTUIASK
PEKNJFIVBKOZUEPPHIWLUBFUDWPIDRJKAZVJKPBRHCRMGNMFWW
CGZAXHXPDELTACGUWBXWNNZNDQYYCIQRJCULIEBQBLLMJEUSZP
RWHHQMBIJWTQPUFNAESPZHAQARNIDUCRYQAZMNVRVZUJOZUDGS
PFGAYBDEECHUXFUZIKAXYDFWJNSAOPJYWUIEJSCORRBVQHCHMR
JNVIPVEMQSHCCAXMWEFSYIGFPIXNIDXOTXTNBCHSHUZGKXFECL
YZBAIIOTWLREPZISBGJLQDALKZUKEQMKLDIPXJEPENEIPWFDLP
HBQKWJFLSEXVILKYPNSWUZLDCRTAYUUPEITQJEITZRQMMAQNLN
DQDJGOWMBFKAIGWEAJOISPFPLULIWVVALLIIHBGEZLGRHRCKGF
LXYPCVPNUKSWCCGXEYTEBAWRLWDWNHHNNNWQNIIBUCGUJYMRYW
CZDKISKUSBPFHVGSAVJBDMNPSDKFRXVVPLVAQUGVUJEXSZFGFQ
IYIJGISUANRAXTGQLAVFMQTICKQAHLEBGHAVOVVPEXIMLFWIYI
ZIIFSOPCMAWCBPKWZBUQPQLGSNIBFADUUJJHPAIUVVNWNWKDZB
HGTEEIISFGIUEUOWXVTPJDVACYQYFQUCXOXOSSMXLZDQESHXKP
FEBZHJAGIFGXSMRDKGONGELOALLSYDVILRWAPXXBPOOSWZNEAS
VJGMAOFLGYIFLJTEKDNIWHJAABCASFMAKIENSYIZZSLRSUIPCJ
BMQGMPDRCPGWKTPLOTAINXZAAJWCPUJHPOUYWNWHZAKCDMZDSR
RRARTVHZYYCEDXJQNQAINQVDJCZCZLCQWQQIKUYMYMOVMNCBVY
ABTCRRUXVGYLZILFLOFYVWFFBZNFWDZOADRDCLIRFKBFBHMAXX
题意中样例:
YQPD
BKEZ
AFYV
二刷: 仿照dfs的思想,只不过这里不是各个方向拓展,故不建议写成递归。
#include
using namespace std;
long long ans = 0;
char s[35][55];
int dir[][2] = {
{
0, 1}, {
1, 0}, {
1, -1}, {
-1, 1}, {
1, 1}};
int maxX = 30, maxY = 50;
//int maxX = 3, maxY = 4;
bool check(int x, int y) {
return x >= 1 && x <= maxX && y >= 1 && y <= maxY;
}
// 选定字符s[x][y], 再找两个字符使之单调递增即可。
// 注意这里方向的迭代要在最外一层,因为方向要固定
void solve(int x, int y) {
for (int i = 0; i < 5; i++) {
int dx = dir[i][0];
int dy = dir[i][1];
int x1 = x + dx, y1 = y + dy;
for (; check(x1, y1); x1 += dx, y1 += dy) {
if (s[x][y] >= s[x1][y1])
continue; // 剪枝
int x2 = x1 + dx, y2 = y1 + dy;
for (; check(x2, y2); x2 += dx, y2 += dy)
if (s[x2][y2] > s[x1][y1])
ans++;
}
}
}
int main() {
for (int i = 1; i <= maxX; i++)
for (int j = 1; j <= maxY; j++)
cin >> s[i][j];
for (int i = 1; i <= maxX; i++)
for (int j = 1; j <= maxY; j++)
solve(i, j);
cout << ans << endl;
}
代码修改自: https://blog.csdn.net/weixin_44190072/article/details/115584303
#include
#include
#include
#include
using namespace std;
/*
将城市转化数字,从而转化为图论结构
北京--1 上海--2 广州--3 长沙--4 西安--5 杭州--6
济南--7 成都--8 南京--9 昆明--10 郑州--11 天津--12
太原--13 武汉--14 重庆--15 南昌--16 长春--17 沈阳--18
贵阳--19 福州--20
*/
struct Node{
int e; //终点
int starttime, endtime; //起始时间,到达时间(转换为分钟表示)
int cost; // 运行时间
Node(int des, int startt, int endt, int time) : e(des), starttime(startt), endtime(endt), cost(time) {
}
Node() {
}
};
vector<vector<Node>> G(25); //存放所有班次信息
map<string, int> m;
long long mintime = 0x3f3f3f3f3f;
long long totaltime = 0;
int vis[25]; //标志去过哪些城市了(每个城市只能去一次,除了北京)
void init(){
m.insert(make_pair("北京",1));
m.insert(make_pair("上海",2));
m.insert(make_pair("广州",3));
m.insert(make_pair("长沙",4));
m.insert(make_pair("西安",5));
m.insert(make_pair("杭州",6));
m.insert(make_pair("济南",7));
m.insert(make_pair("成都",8));
m.insert(make_pair("南京",9));
m.insert(make_pair("昆明",10));
m.insert(make_pair("郑州",11));
m.insert(make_pair("天津",12));
m.insert(make_pair("太原",13));
m.insert(make_pair("武汉",14));
m.insert(make_pair("重庆",15));
m.insert(make_pair("南昌",16));
m.insert(make_pair("长春",17));
m.insert(make_pair("沈阳",18));
m.insert(make_pair("贵阳",19));
m.insert(make_pair("福州",20));
memset(vis, 0, sizeof(vis));
}
void dfs(int s, int endt, int len) //s为起点城市,endt为到达此城市的时间,len为当前旅游过哪些城市了
{
if(s == 1 && len > 0) //到达北京就要回溯 (除了开始从北京出发)
{
bool flag = true;
for(int i = 1; i <= 20; i++) //检查是否旅游完毕
if(vis[i] == 0)
flag = false;
vis[1] = 0; //北京始终允许反复访问(在北京多次中转)
if(flag) //走遍所有地点(19个旅游城市+1个终点城市北京)
mintime = min(mintime, totaltime);
/*
注:如果直接if(len==20)判断的话,会忽略掉可以经过北京中转的情况,
虽然此题结果经过北京中转不会使时间减少,但是我们设计程序应该考虑全面
*/
return;
}
for(int i = 0; i < G[s].size(); i++)
{
Node r = G[s][i];
if(vis[r.e] == 0) //目的城市没去过
{
vis[r.e] = 1;
long long temp = totaltime;
//time1: 此班车的运行时间
totaltime += r.cost;
//time2: 班次间隔时间(24h内)
if(s != 1 && r.starttime > endt) //此班车出发时间和上一班结束时间的关系
totaltime += r.starttime - endt;//休息时间(当日)
if(s != 1 && r.starttime < endt)
totaltime += r.starttime - endt + 1440; //跨日
//time3: 从北京出发时的等车时间
if(s == 1)
{
if(r.starttime > 720) //十二点出发
totaltime += r.starttime-720;
else
totaltime -= r.starttime - 720 + 1440; //只有等到明天才能出发了
}
//最优性剪枝:不剪枝会花跑很久
if(totaltime > mintime)
{
totaltime = temp;
continue;
}
dfs(r.e, r.endtime, len + 1);
vis[r.e] = 0;
totaltime = temp;
}
}
}
int main(){
init();
//freopen("trip.txt","r",stdin); //注意:从文件中读取文字信息会发生乱码
//读入某行信息也可以使用getline(cin,str);
string str;
for(int i = 1; i <= 5; i++) //读入第一行无用数据
cin >> str;
for(int i = 1; i <= 132; i++) //共有132班车
{
cin >> str; //去掉无用的班次名字
string src, des; //起始站-->终点站
string s, t; //出发时间-->到达时间
cin >> src >> des >> s >> t;
//换算时间为分钟表示
int a, b;
a = (s[0] - '0') * 600 + (s[1] - '0') * 60 + (s[3] - '0') * 10 + (s[4] - '0');
b = (t[0] - '0') * 600 + (t[1] - '0') * 60 + (t[3] - '0') * 10 + (t[4] - '0');
int cost; //运行时间
if(a < b)
cost = b - a;
else
cost = b - a + 1440; //+1天
//存入图中 m(string->int)
G[m[src]].push_back(Node(m[des], a, b, cost));
}
//检验所有班次以及城市信息的录入情况
//for(int i=0;i<25;i++)
// for(int j=0;j
// {
// Node r=G[i][j];
// cout<
// }
dfs(1, 0, 0); //从北京出发
mintime += 1440 * 19; //加上19天的停留(如果经过北京中转,不会停留24h)
/*任意两趟班次之间:前一班的到达时间 到 下一班的发车时间间隔都是小于24h
例如:前一班15:30到,下一班16.30出发 需要休息一天+24h
前一班15.30到,下一班08.30出发 也需要休息一天+24h
*/
cout << mintime;
}
//注意:班次信息为每天固定发车,即每天都会同一时间发同一班车
//ans : 47373
答案: 47373
车次 出发站 到达站 出发时间 到达时间
G169 北京 上海 16:40 22:35
G21 北京 上海 19:08 23:40
G18 上海 北京 17:55 22:36
G68 广州 北京 11:13 21:10
G67 北京 广州 12:13 22:19
G1305 上海 广州 15:25 23:38
G86 广州 上海 08:00 14:50
G6122 广州 长沙 21:00 23:36
G6117 长沙 广州 17:55 20:39
G502 长沙 北京 07:36 14:24
G503 北京 长沙 14:41 21:14
G1359 上海 长沙 15:37 20:59
G1348 长沙 上海 09:00 13:41
G362 西安 上海 08:49 14:45
G1936 上海 西安 16:12 22:54
G87 北京 西安 14:00 18:20
G88 西安 北京 13:30 17:55
G98 西安 广州 09:57 17:39
G836 广州 西安 11:24 20:09
G1404 广州 杭州 15:56 23:25
G20 杭州 北京 07:48 12:20
G39 北京 杭州 19:04 23:22
G7355 上海 杭州 21:30 22:28
G7558 杭州 上海 07:06 08:12
G300 济南 上海 06:50 11:40
G333 北京 济南 19:55 21:55
G336 济南 北京 07:45 09:33
G2056 广州 济南 08:05 18:34
G2058 济南 广州 10:14 20:49
G350 成都 北京 07:00 14:46
G89 北京 成都 06:53 14:38
G1888 成都 南京 11:28 22:00
G7180 上海 南京 10:05 11:29
G7003 南京 上海 08:00 09:39
G7613 南京 杭州 16:19 17:40
G7604 杭州 南京 12:09 13:30
G1540 昆明 南京 10:20 21:14
G1539 南京 昆明 09:05 19:40
G2883 成都 昆明 08:51 14:29
G2884 昆明 成都 12:16 17:57
G1538 昆明 郑州 08:46 18:48
G1537 郑州 昆明 10:38 20:49
G2001 郑州 西安 07:52 10:24
G2002 西安 郑州 08:10 10:29
G2231 西安 重庆 17:06 22:56
G2232 重庆 西安 07:05 12:37
G8594 重庆 成都 06:50 08:07
G8599 成都 重庆 22:12 23:29
G1709 天津 重庆 08:05 19:39
G1710 重庆 天津 10:49 22:45
G8901 北京 天津 22:10 22:45
G8928 天津 北京 19:08 19:46
G2609 天津 太原 10:40 14:15
G2610 太原 天津 14:43 18:12
G1954 太原 上海 12:26 21:17
G1952 上海 太原 08:10 17:28
G686 郑州 太原 13:17 17:16
G688 太原 郑州 17:38 21:38
G1864 太原 杭州 12:50 21:10
G1862 杭州 太原 07:14 15:50
G91 北京 太原 08:40 11:07
G92 太原 北京 08:33 11:00
G694 太原 武汉 16:37 22:29
G692 武汉 太原 09:48 16:00
G1722 武汉 上海 08:00 11:53
G1720 上海 武汉 13:51 17:50
G858 西安 武汉 15:18 19:48
G856 武汉 西安 09:17 14:27
G365 天津 武汉 14:56 20:41
G366 武汉 天津 14:30 20:32
G294 长沙 天津 08:47 16:56
G292 天津 长沙 10:58 18:50
G696 长沙 太原 09:23 17:55
G698 太原 长沙 10:46 18:18
G1391 杭州 昆明 11:43 22:53
G1392 昆明 杭州 09:06 20:18
G1514 昆明 南昌 16:00 22:54
G1511 南昌 昆明 08:25 15:38
G1462 南昌 杭州 12:24 15:28
G1451 杭州 南昌 12:30 15:26
G1244 济南 长春 07:42 15:07
G1242 长春 济南 15:33 22:35
G8033 沈阳 长春 06:42 08:40
G1290 长沙 长春 07:21 21:09
G1292 长春 长沙 08:47 22:08
G400 长春 北京 08:32 14:48
G399 北京 长春 15:20 21:45
G1886 南京 成都 08:07 17:54
G579 南京 长沙 09:27 14:10
G580 长沙 南京 15:53 20:40
G1484 贵阳 南京 07:58 18:02
G2335 南京 贵阳 12:07 21:58
G2105 长沙 贵阳 13:17 16:55
G2116 贵阳 长沙 08:11 11:26
G2201 郑州 成都 07:10 13:19
G2212 成都 郑州 16:57 23:04
G1814 上海 郑州 14:15 18:12
G370 郑州 上海 07:33 12:02
G1274 武汉 沈阳 07:23 19:03
G1272 沈阳 武汉 07:32 19:20
G2869 重庆 昆明 07:43 11:55
G2870 昆明 重庆 14:52 19:09
G1335 重庆 上海 08:48 20:56
G1333 上海 重庆 11:39 23:29
G1759 南昌 重庆 07:08 14:45
G1761 重庆 南昌 15:12 22:23
G1493 南京 南昌 13:00 17:21
G1496 南昌 南京 09:04 13:25
G5314 南昌 福州 08:13 11:09
G5312 福州 南昌 18:30 21:25
G1256 长春 上海 11:53 22:54
G1258 上海 长春 09:08 20:05
G1284 沈阳 成都 07:02 21:47
G1282 成都 沈阳 09:06 23:13
G217 北京 沈阳 13:30 17:15
G218 沈阳 北京 08:11 11:58
G2604 沈阳 太原 15:34 23:00
G2602 太原 沈阳 07:44 15:14
G8664 贵阳 成都 19:15 22:35
G8691 成都 贵阳 11:11 14:31
G2958 贵阳 广州 14:03 20:26
G2960 广州 贵阳 07:27 13:43
G1521 武汉 贵阳 08:01 13:25
G1524 贵阳 武汉 14:23 19:33
G1609 福州 广州 08:16 14:15
G1607 广州 福州 14:55 21:05
G1696 昆明 福州 11:11 22:02
G1698 福州 昆明 08:41 19:28
G1636 福州 上海 12:26 16:55
G1631 上海 福州 07:54 12:15
G1642 福州 杭州 14:45 18:32
G1641 杭州 福州 18:55 22:38
我没明白题意,不知道所有可能的骰子能多少种,感觉题目表达不清楚(疯狂甩锅…)
代码参考: https://blog.csdn.net/qq_43319748/article/details/109651376
那位博主的代码是java的,我只找到Java的题解…按着他的思路写了个c++的,其实差不多。
#include
using namespace std;
int main(){
int sum = 0;
for (int i = 1; i <= 60; i++) {
//取60位
int cnt = 0;
int x = 1; //每次都从1开始找,避免漏数
//因为是包含关系,约数个数大于等于都符合要求
while(cnt < i) {
cnt = 0; //记录当前x的约数个数
for (int j = 1; j <= x; j++) {
if (x % j == 0)
cnt++;
}
x++;
}
if (cnt >= i) {
//因为在循环结束后x多加了个1,这里减去
x--;
sum += x;
}
}
cout << sum << endl; // 101449
}
答案:101449
二刷:
#include
using namespace std;
int main() {
int sum = 0, cnt, x;
for (int i = 1; i <= 60; i++) {
x = 1; // 每次从1开始找
while (true) {
cnt = 0;
for (int j = 1; j <= x; j++)
if (x % j == 0)
cnt++;
if (cnt >= i)
break;
x++;
}
sum += x;
}
cout << sum << endl; // 101449
}
9 5
+++++++++
+++++++++
+++++++++
+++++++++
+++++++++
***+*****
+++++++++
+++++++++
+++++++++
样例输出
16
思路: BFS走迷宫的题目,只不过多了体积的判断而已。
代码来自: https://blog.csdn.net/weixin_46239370/article/details/109584332, 有小部分改动
#include
#include
using namespace std;
struct node {
int x, y, time;
};
const int N = 310;
int n, k;
char maze[N][N];
bool vis[N][N];
int dr[3] = {
2, 1, 0};
int dir[][2] = {
{
-1, 0}, {
0, 1}, {
1, 0}, {
0, -1}};
int bfs() {
queue<node> q;
q.push({
3, 3, 0});
vis[3][3] = true;
while(q.size()) {
// 或 !q.empty()
node cur = q.front();
q.pop();
// 到达终点
if(cur.x == n - 2 && cur.y == n - 2)
return cur.time;
if(cur.time / k < 2)
// 只有体积大于2时,才有可能需要原地不动
q.push({
cur.x, cur.y, cur.time + 1});
for (int i = 0; i < 4; i ++) {
int nx = cur.x + dir[i][0];
int ny = cur.y + dir[i][1];
int fat = cur.time / k > 2 ? 0 : dr[cur.time / k]; // 此时小明的半径
if(nx - fat < 1 || nx + fat > n || ny - fat < 1 || ny + fat > n)
continue;
if(vis[nx][ny])
continue;
bool flag = false; // 判断胖子所占范围内是否有障碍物
for (int j = nx - fat; j <= nx + fat && !flag; j ++)
for (int k = ny - fat; k <= ny + fat && !flag; k ++)
if(maze[j][k] == '*')
flag = true;
if(flag)
continue;
q.push({
nx, ny, cur.time + 1});
vis[nx][ny] = true;
}
}
// 无法到达终点, 该题应该不会出现此情况
return -1;
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j++)
cin >> maze[i][j];
cout << bfs() << endl;
}
这里可以看这个: https://blog.csdn.net/qq_45892987/article/details/117307579