蓝桥杯官网 辅导资料
往下翻,这个就是了。
html
【解题思路】
bit是位,B是字节,1B = 8bit,除此以外任意两个都是1024的距离。
因此手机的4GB内存就是
个字节(B)node
【代码】ios
#include<iostream> using namespace std; int main(){ int res = 15.125*1024; printf("%d", res); return 0; }
【解题思路】
填空题怎么方便怎么来,枚举。
【代码】web
#include<iostream> using namespace std; int main(){ int n = 1200000; int cnt = 0; for(int i=1; i<=n; i++){ if(n%i == 0){ cnt++; } } printf("%d", cnt); return 0; }
【解题思路】编程
有: 数组
要使n0最大,n1要最小,则n1 = 0数据结构
因此: app
【代码】svg
#include<iostream> using namespace std; int main(){ int n = 2019; printf("%d", (n+1)/2); return 0; }
【解题思路】
枚举1~2019,取每一个数的每一位判断是否为9,遇到九就不用继续判断剩余的位数了。学习
【代码】
#include<iostream> using namespace std; bool hasEight(int n){ bool flag = false; while(n>0){ if(n%10 == 9){ flag = true; break; } n /= 10; } return flag; } int main(){ int n = 2019, ans = 0; for(int i=1; i<=2019; i++){ if(hasEight(i)) ans++; } printf("%d", ans); return 0; }
【解题思路】
最大数只有7位,n最大1000000(10^6),每个数枚举位数判断复杂度是O(1)的,n个数O(7n),能够枚举。
【代码】
#include<iostream> using namespace std; bool ok(int n){ if(n < 10) return true; bool flag = true; int x = n%10; n /= 10; while(n>0){ if(n%10 > x){ flag = false; break; } //更新x和n x = n % 10; n /= 10; } return flag; } int main(){ int n; scanf("%d", &n); int ans = 0; for(int i=1; i<=n; i++){ if(ok(i)){ ans++; } } printf("%d", ans); return 0; }
【解题思路】
枚举每个数,看左边有没有比它小的 && 右边有没有比它大的,时间复杂度O(n^2),不会超时。
【代码】
#include<iostream> using namespace std; const int maxn = 10010; int num[maxn]; int main(){ int n; scanf("%d", &n); for(int i=0; i<n; i++){ scanf("%d", &num[i]); } int ans = 0, x; for(int i=1; i<n-1; i++){ x = num[i]; bool hasSmall = false, hasBig = false; for(int j=0; j<i; j++){ if(num[j] < x){ hasSmall = true; break; } } for(int j=i+1; j<n; j++){ if(num[j] > x){ hasBig = true; break; } } if(hasSmall && hasBig){ ans++; } } printf("%d", ans); return 0; }
【解题思路】
由于要能把单词划分为辅音元音辅音元音四个部分,只要从头至尾扫描一边字符串便可,时间复杂度为O(n),n为字符串长度。
我是这样作的,设置一个标识last表示当前字母的前一个字母是不是元音,初始值为输入字符串的第一个字母是否为元音,若是是,last = true,这是程序能够直接退出了,由于第一部分必须是辅音。
设置idx,代表当前字母处于第几部分。
扫描过程:
若是第一个字母是辅音,last = false,而后从第二个字母开始,若是:
最后若是idx为4代表恰好符合要求的四段,输出yes,反之输出no
【例如】 lanqiao
【代码】
#include<iostream> #include<cstring> using namespace std; string vowel = "aeiou"; bool isVowel(char ch){ bool flag = false; for(int i=0; i<vowel.length(); i++){ if(vowel[i] == ch){ flag = true; break; } } return flag; } int main(){ string str; cin>>str; bool last = false;//前一个字母是元音为true if(isVowel(str[0])) last = true; //辅音元音辅音元音 int idx = 1; if(last){ printf("no"); } else{ for(int i=1; i<str.length(); i++){ if(last){ //若是前一个是元音而且当前字母也是元音,什么都不作 //若是当前字母是辅音,idx++; if(!isVowel(str[i])){ idx++; last = false; } } else{ //前一个是辅音 //当前是元音,idx++ if(isVowel(str[i])){ idx++; last = true; } } } if(idx == 4){ printf("yes"); } else{ printf("no"); } } return 0; }
【解题思路】
这是一个典型的BFS题目,总共有nm个位置,习惯说结点,那么最多每一个结点都入队一次,时间复杂度为O(nm)
结点用结构体表示,除告终点的坐标,还须要记录该结点是第几个月长出来的,也就是层数。
struct node{ int x, y; int layer; };
用到的变量有:
上述都放在全局,在竞赛时这样很方便,不会涉及到引用之类的,没啥坏处,因此能放在全局我就不会传参。
读入数据时,若是是“g”就将matrix[i][j]设为true,把该结点入队(注意层数设置为0)并设置为已入队,而后进行BFS。
BFS时取出队首元素,若是该元素的layer == k,就直接退出了(只看第k月草的长势状况),不然枚举它周围的结点,并将层数设置为layer+1,而后若是没入过队而且没出界,就加入队列。
注意不须要管该地如今有没有草,都须要入队。
【代码】
#include<iostream> #include<queue> using namespace std; const int maxn = 1010; struct node{ int x, y; int layer; }; //增量矩阵 int X[4] = {0, 0, 1, -1}; int Y[4] = {1, -1, 0, 0}; bool matrix[maxn][maxn];//matrix[i][j] = true表示(i, j)处有草 bool inq[maxn][maxn] = {false};//检查坐标为(i, j)的点是否已经入过队列 queue<node> q; int n, m, k; bool judge(int i, int j){ //越界 if(i<0||i>=n||j<0||j>=m) return false; //入过队 if(inq[i][j]) return false; return true; } void BFS(){ while(!q.empty()){ node top = q.front(); q.pop(); if(top.layer == k){ break; } node temp; temp.layer = top.layer + 1; //层数为父节点加1 //枚举四个方向 for(int i=0; i<4; i++){ temp.x = top.x + X[i]; temp.y = top.y + Y[i]; if(judge(temp.x, temp.y)){ matrix[temp.x][temp.y] = true; inq[temp.x][temp.y] = true; q.push(temp); } } } } int main(){ scanf("%d%d", &n, &m); getchar(); char ch; node temp; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ scanf("%c", &ch); if(ch == '.') matrix[i][j] = false; else{ matrix[i][j] = true; temp.x = i; temp.y = j; temp.layer = 0;//一开始就种了,至关于第0个月的状况 q.push(temp); inq[i][j] = true; } } getchar();//一行读完了记得读掉空行 } scanf("%d", &k); BFS(); for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if(matrix[i][j]) printf("g"); else printf("."); } printf("\n"); } return 0; }
【解题思路】
蓝桥杯总会考一题相似这样的搜索问题。题意清楚可是又根本感受无从下手。这种时候要尽力想办法一层一层剥开来考虑,首先想一个能表达出结果的方法(我以为有点像动态规划找表达式的感受),而后想办法怎么才能让这个表达规模变小(好像又有点分治的意思),直到能求出答案。
因此用f(i, j)表示第一个数是i,第二个数是1~j的序列个数,结果能够表达为f[n, n),那表达式是:
就是一次减少一层规模,展开一层的感受,第一项是剩余的第一个数是i,第二个是1~j-1的序列个数,第二项是展开的那一层,也就是第一个数是i,第二个数是j的序列个数,那么有两种:
【代码】
#include<iostream> using namespace std; const int maxn = 1010; const int MOD = 10000; int mem[maxn][maxn]; int n; int dfs(int i, int j){ //f(i,j)表示前一个数是i,当前数是1到j的合法序列的个数 if(j <= 0) return 0; if(mem[i][j] != 0) return mem[i][j]; //展开一层(展开前一个数是i,当前数是j的合法序列这层,个数为 1 + dfs(i, abs(i - j) - 1)) else return mem[i][j] = (dfs(i, j-1) + 1 + dfs(j, abs(i-j)-1))%MOD; } int main(){ scanf("%d", &n); int res = dfs(n, n); printf("%d", res); return 0; }
【解题思路】
一看题:直接结构体两次排序,这么简单啊。
果真是我想多了…
果真看懂题目才是最重要的,题目表达的是:他但愿选出的第一个节目尽量好看,在此前提下但愿第二个节目尽量好看,依次类推。
并非找前m大的数按照输入顺序输出,而是找字典序最大的m个数组成的序列。
举个栗子:
6 3
3 4 8 7 1 2
若是只是找前m大的数,那么(结构体先按好看值排序再按索引排序)会输出:
4 8 7
但题目的意思须要输出:
8 7 2
由于即便第一个序列的总好看值更大,但第二个序列才知足了第一个节目尽量好看,也就是字典序大的要求。
那么可使用two pointers来解决(找的是区间最值):
两个指针p1, p2分别指向区间的首尾,初始时p1 = 0, p2 = n-m, 由于第一个数只能在这个区间内,若是p2再大,就不能保证总共能取到m个数。
遍历[p1, p2]范围内的好看值数组,用pm指示区间内最大元素的下标,MAX指示区间内最大的元素(记录好找最大值),输出MAX。
更新区间
直到
, 或者
的状况说明区间内就一个数,直接输出数组后的所有数就好了,也就是节目都得上,由于初始时p2的取值就使得后面的数只有m-1个了。
仍是这个栗子:
6 3
3 4 8 7 1 2
最终获得了八、七、2,这是六个数中取三个数的序列中字典序最大的一个。
【代码】
复杂度是O(n^2),会超时,我这就去学习ST和线段树。
#include<iostream> #include<algorithm> using namespace std; const int maxn = 100010; int show[maxn]; int main(){ int n, m; scanf("%d%d", &n, &m); for(int i=0; i<n; i++){ scanf("%d", &show[i]); } //在n个数中找出字典序最大的m个数的序列 int p1 = 0, p2 = n-m, pm; while(p1 < p2 && p2 < n){ int MAX = -1; for(int i=p1; i<=p2; i++){ if(show[i] > MAX){ MAX = show[i]; pm = i; } } printf("%d ", show[pm]); //更新区间 p1 = pm+1; p2++; } //p1和p2相等,说明后面的节目都被选中了 if(p2 < n){ for(int i=p2; i<n; i++){ printf("%d ", show[i]); } } return 0; }
感受蓝桥杯很爱考数学问题。