备战蓝桥杯--历届试题题解
来源:互联网 发布:创建表时外键的sql语句 编辑:程序博客网 时间:2024/06/05 15:33
3月20号将是我第一次外出比赛。 虽然是蓝桥杯。但是还是刷新题目下热热身
蓝桥杯--历年试题 【编程大题】
PREV-1 核桃的数量 最小公倍数
小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:
1. 各组的核桃数量必须相同
2. 各组内必须能平分核桃(当然是不能打碎的)
3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛)
思路:太水了。 就是找一个数并且能同时整除abc,最小公倍数
#include<iostream>#include<stdio.h>#include<cmath>using namespace std;int gcd(int a,int b){return b==0?a:gcd(b,a%b);}int lcm(int a,int b){return a/gcd(a,b)*b;}int main(){int num,ans=1;for(int i=0;i<3;i++){scanf("%d",&num);ans=lcm(ans,num);}printf("%d\n",ans);return 0;}
PREV-2 打印十字图 文字图
[暂时做不出来。。。讨厌这种画图题。ORZ。]PREV-3 带分数 搜索
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
思路:将式子看出N=A+B/C的形式,观测到数字1~9分别出现且只出现一次这一条件就可以想到枚举全排列。然后将全排列分成3个部分。分别
分别是A B C三个部分,然后判断(N-A)*C==B,注意ABC都是至少需要一个数来构成。全排列的9的数字中[记为1-9],A只能从1枚举到7
B只能从2枚举到8,C只能从3枚举到9. 简单优化一下:当A组成的数字大于N时就不应该继续枚举了。因为永远得不到结果。
#include<iostream>#include<stdio.h>#include<cmath>#include<time.h>#include<string>#include<cstring>#include<algorithm>using namespace std;const int MAXN=1000*1000+5;int num[10],vis[MAXN];int get_num(int st,int ed){//全排列的st到ed组成的数字 int m=0;for(int i=st;i<=ed;i++){m=m*10+num[i];}return m;}int main(){int n,ans;while(scanf("%d",&n)!=EOF){ans=0;int A,B,C;for(int i=0;i<9;i++){num[i]=i+1;}do{//枚举全排列 for(int i=0;i<9;i++){A=get_num(0,i);if(A>=n){//优化。 break;}for(int j=i+1;j<8;j++){B=get_num(i+1,j);C=get_num(j+1,8);if(B==(n-A)*C){ans++;}}}}while(next_permutation(num,num+9));printf("%d\n",ans);}return 0;}
PREV-4 剪格子 搜索
如下图所示,3 x 3 的格子中填写了一些整数。
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
程序先读入两个整数 m n 用空格分割 (m,n<10)。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
10 1 52
20 30 1
1 2 3
1 1 1 1
1 30 80 2
1 1 1 100
思路:因为记录的是最上角的的分割区可能包含的最小的格子数目,所以很容易就会想到从左上角开始深搜。很可惜。这样做案例2是无法得到正确答案的。因为一般的深搜只能按一个方向[上下左右]一直搜索,而不能想案例2那样"拐弯"搜索,但是不管怎么搜索,正确结果的搜索区域即不管怎么"拐弯",得到的区域都是连续的,那么我们可以从所有位置开始搜索,当满足条件并且同时搜索到左上角的位置时就可以记录了。虽然是100分过,但是我还是觉得这题测试数据不够严谨,即使暴力所有点开始dfs搜索都还是可以找反例。即结果区域呈"十字架/T字形"的话,暴力起点搜还是不会得到正确结果的。不过没想到更好的办法了。
#include<iostream>#include<stdio.h>#include<cmath>#include<time.h>#include<string>#include<cstring>#include<algorithm>using namespace std;const int MAXN=15;int num[MAXN][MAXN],n,m,s,ans;int vis[MAXN][MAXN],dist[4][2]={0,1,0,-1,1,0,-1,0};//标记数组[回溯用],方向向量 bool check(int x,int y){//是否越界 if(x>=0&&x<n&&y>=0&&y<m){return true;}return false;}void dfs(int x,int y,int val,int total){//x,y:当前位置 val:当前的数字和 total:当前搜索的区域包括多少个数字 if(val>s||total>=ans){//剪枝:当前数已经大于整体的一般,或者 return;//包括的区域数字已经大于当前最优解 }if(val==s&&vis[0][0]){//到最终状态并且搜索到左上角 ans=min(ans,total);}for(int i=0;i<4;i++){int nextx=x+dist[i][0];int nexty=y+dist[i][1];if(check(nextx,nexty)&&!vis[nextx][nexty]){vis[nextx][nexty]=1;dfs(nextx,nexty,val+num[nextx][nexty],total+1);vis[nextx][nexty]=0;}}}int main(){while(scanf("%d%d",&m,&n)!=EOF){ans=105;int sum=0;memset(vis,0,sizeof(vis));for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&num[i][j]);sum+=num[i][j];}}if(sum%2)//如果不能分成2部分 {printf("0\n");continue;}s=sum/2;//最终需要得到的结果S for(int i=0;i<n;i++){for(int j=0;j<n;j++){//暴力每个起点搜索 memset(vis,0,sizeof(vis));vis[i][j]=1;dfs(0,0,num[i][j],1);}}if(ans==105)//无法平分 {printf("0\n");}else{printf("%d\n",ans);}}return 0;}
PREV-5 错误票据 排序
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
要求程序首先输入一个整数N(N<100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000),请注意行内和行末可能有多余的空格,你的程序需要能处理这些空格。
每个整数代表一个ID号。
要求程序输出1行,含两个整数m n,用空格分隔。
其中,m表示断号ID,n表示重号ID
5 6 8 11 9
10 12 9
164 178 108 109 180 155 141 159 104 182 179 118 137 184 115 124 125 129 168 196
172 189 127 107 112 192 103 131 133 169 158
128 102 110 148 139 157 140 195 197
185 152 135 106 123 173 122 136 174 191 145 116 151 143 175 120 161 134 162 190
149 138 142 146 199 126 165 156 153 193 144 166 170 121 171 132 101 194 187 188
113 130 176 154 177 120 117 150 114 183 186 181 100 163 160 167 147 198 111 119
思路:水题。按照题目意思模拟即可,主要考察字符串的处理[字符串->数字的转换]。断点和重复只有一个。记录数字的最大值和最小值。开个数组记录那些数字已经出现过,然后暴力找最小值到最大值那个没出现过。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<cmath>using namespace std;const int MAXN=100000+5;const int MAXL=20000000;int num[MAXN],minnum,maxnum;char str[MAXL];int main(){int n,repeat,vacancy;while(scanf("%d",&n)!=EOF){memset(num,0,sizeof(num));minnum=MAXN+1;maxnum=-1;getchar();for(int i=0;i<n;i++){gets(str);int len=strlen(str);for(int j=0;j<len;j++){if(str[j]!=' '){int val=0;while(str[j]!=' '&&j<len){val=val*10+str[j]-'0';j++;}maxnum=max(maxnum,val);minnum=min(minnum,val);if(num[val]==0){//是否出现过 num[val]=1;}else{//重复出现 repeat=val;}}}}for(int i=minnum;i<=maxnum;i++){//找断点 if(num[i]==0){vacancy=i;break;}}printf("%d %d\n",vacancy,repeat);}return 0;}
PREV-6 翻硬币 贪心
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:**oo***oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000
一个整数,表示最小操作步数。
o****o****
*o***o**o***
思路:因为只能一次翻2个,所以想匹配最左边,如果匹配则继续匹配下一个位置,否则就必须翻这个位置的硬币[同时改变他下一个位置的硬币,因为一翻就会改动2个位置],模拟就好了
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<cmath>using namespace std;const int MAXL=1000+5;char st[MAXL],ed[MAXL];char chang(char a){return a=='*'?'o':'*';}int main(){while(scanf("%s",st)!=EOF){scanf("%s",ed);int step=0,len=strlen(st);for(int i=0;i<len;i++){if(st[i]!=ed[i])//不匹配 {step++;st[i+1]=chang(st[i+1]);//改变下一个位置 }}printf("%d\n",step);}return 0;}
PREV-7 连号区间数 并查集
小明这些天一直在思考这样一个奇怪而有趣的问题:
在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:
如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。
当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。
第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。
第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。
输出一个整数,表示不同连号区间的数目。
3 2 4 1
3 4 2 5 1
思路:起初我是暴力的,没暴力每个起点和终点。然后将起点和终点的数排序。记L=起点位置,R=终点位置。那么用个vector把这个区间的数都push进去,然后排序一遍,然后最大值-最小值+1=size()的话就满足条件。然后这样做只能得60分。因为是O(n*n*nlogn)。但是想一下。只会出现1-N的数字。所以只需要继续L,R区域里的最大值和最小值。如果区域最大值-最小值=区域个数,那么就一定满足要求。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<cmath>using namespace std;const int MAXN=50000+5;int num[MAXN];int main(){int n;while(scanf("%d",&n)!=EOF){int ans=0;for(int i=0;i<n;i++){scanf("%d",&num[i]);}for(int i=0;i<n;i++){int maxnum=num[i];int minnum=num[i];for(int j=i+1;j<n;j++){maxnum=max(maxnum,num[j]);minnum=min(minnum,num[j]);if(maxnum-minnum==j-i){ans++;}}}printf("%d\n",ans+n);//+n表示区间[L,L]即本身一定满足条件 }return 0;}
PREV-8 买不到的数目 数论 动态规划
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
两个正整数,表示每种包装中糖的颗数(都不多于1000)
一个正整数,表示最大不能买到的糖数
思路:估算结果范围+暴力DP。。。因为没想到其他比较好的办法,所以就估算结果会在1000*1000内。假设输入的数为a,b 先dp筛掉a的倍数。然后i从b-1000*1000筛选b的倍数的i和能够凑成i-b的i,看代码吧。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<cmath>#include<time.h>using namespace std;const int MAXN=1000*1000+1;bool dp[MAXN];int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){if(n==1||m==1){//不知道会不会有1这样的数据出现,因为1是能组成任何大于1数printf("0\n");continue;}memset(dp,false,sizeof(dp));if(n>m){swap(n,m);}for(int i=n;i<MAXN;i+=n){//筛选a的倍数 dp[i]=true;}for(int i=m;i<MAXN;i++){//筛选b的倍数和能凑成i-b的数 if(dp[i-m]||i%m==0){dp[i]=true;}}int ans=-1;//找最大的不能组成的数 for(int i=0;i<MAXN;i++){if(!dp[i]){ans=max(ans,i);}}printf("%d\n",ans);}return 0;}
PREV-9 大臣的旅费 深度优先遍历
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
输出一个整数,表示大臣J最多花费的路费是多少。
1 2 2
1 3 1
2 4 5
2 5 4
大臣J从城市4到城市5要花费135的路费。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<cmath>#include<time.h>using namespace std;const int MAXN=1000005;long long int dist[MAXN]; struct Node{int to,val;Node(int a,int b):to(a),val(b){}};vector<Node>G[MAXN];void init(){dist[0]=0;int len=11;for(int i=1;i<MAXN;i++){dist[i]=dist[i-1]+len;len++;}}int diameter; //保存最长路径int DFS(int x, int px){ // px是x的父親int h1 = 0, h2 = 0; // 紀錄最高與次高的高度int d = G[x].size();for (int i = 0; i < d; i++){int v = G[x][i].to,w=G[x][i].val;if (v != px){int h = DFS(v, x) + w;if (h > h1) h2 = h1, h1 = h;else if (h > h2) h2 = h;}}diameter = max(diameter, h1 + h2); return h1;}int main(){int n;init();while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++){G[i].clear();}int u,v,w;for(int i=1;i<n;i++){scanf("%d%d%d",&u,&v,&w);G[u].push_back(Node(v,w));G[v].push_back(Node(u,w));}diameter=0;DFS(1, -1);cout<<dist[diameter]<<endl;}return 0;}
PREV-10 幸运数 堆
思路:无脑按照题目要求把表打出来。1000*150这个范围内还是很快可以把表打出来的。但是极限数据就非常慢。 题目要求的1000*1000卡了好几秒才能读数据。但是估计数据真心水,1000*150的表都能100分过。注意下不能包括n,m。 暂时没想到什么能解决1000*1000的高效办法。有人说可以用打素数表的方法,但是我是没想出来。这个和素数关系好像不大,因为要筛的是按位置来筛,而不是按照数字本身来特点来筛。 无力,小数据水过。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<cmath>#include<time.h>using namespace std;const int MAXN=1000*150;//小数据。 vector<int>lucky;//幸运数表 void init(){for(int i=1;i<MAXN;i+=2)//先将1 3 5 7...加入表 {lucky.push_back(i);}for(int i=1;i<lucky.size();i++){int num=lucky[i];//获得第i个幸运数 if(num-1>=lucky.size()){//剪枝,当前数已经大于表的大小,后面的数都无法筛 break;}for(int j=1;j*num-j<lucky.size();j++){//筛掉位置为index的数,-j时因为 erase删除数据的同时会将后面的数进行 int index=j*num-j;//补齐操作。相当于简单前面已经删过的数的个数才是 lucky.erase(lucky.begin()+index);//要筛的正确位置 }}//cout<<"size():"<<lucky.size()<<endl;}int main(){//clock_t s1,s2;//s1=clock();init();int n,m;while(scanf("%d%d",&n,&m)!=EOF){int L=upper_bound(lucky.begin(),lucky.end(),n)-lucky.begin();//找到大于n的数的位置 int R=lower_bound(lucky.begin(),lucky.end(),m)-lucky.begin();//找到小于等于m的数的位置 if(R>0)//因为不能包括m所以减掉 {R--;//因为可能r--后出现l>r的情况}printf("%d\n",max(0,R-L+1));//所以输出时判断结果不为负数 //s2=clock();//printf("%f ms\n", (double)(s2 - s1));}return 0;}
PREV-12 危险系数 割点
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数DF(x,y):
对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。
本题的任务是:已知网络结构,求两站点之间的危险系数。
输入数据第一行包含2个整数n(2 <= n <= 1000), m(0 <= m <= 2000),分别代表站点数,通道数;
接下来m行,每行两个整数 u,v (1 <= u, v <= n; u != v)代表一条通道;
最后1行,两个数u,v,代表询问两点之间的危险系数DF(u, v)。
1 3
2 3
3 4
3 5
4 5
5 6
1 6
思路:模拟暴力删除点[除了起点和终点],然后跑一次DFS看看连不连通。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>using namespace std;const int MAXN=1000+5;#define INF 0x3f3f3f3fvector<int>G[MAXN];int ans,st,ed,vis[MAXN];bool flag;//判断是否连通 void dfs(int u){if(u==ed||flag){flag=true;return;}for(int i=0;i<G[u].size()&&!flag;i++){int v=G[u][i];if(!vis[v]){vis[v]=1;dfs(v);vis[v]=0;}}}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){for(int i=1;i<=n;i++){G[i].clear();}for(int i=0;i<m;i++){int u,v;scanf("%d%d",&u,&v);G[u].push_back(v);G[v].push_back(u);}memset(vis,0,sizeof(vis));scanf("%d%d",&st,&ed);vis[st]=1; ans=0;dfs(st);//先跑一边看看原图是否可达 if(flag==false){printf("-1\n");}else{for(int i=1;i<=n;i++){if(i==st||i==ed)//枚举删除的点 {continue;}flag=false;vis[i]=1;dfs(st);if(!flag){ans++;}vis[i]=0;//记得取消标记。因为每次只删除一个点 }printf("%d\n",ans);}}return 0;}
PREV-13 网络寻路 构图
X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。
源地址和目标地址可以相同,但中间节点必须不同。
如下图所示的网络。
1 -> 2 -> 3 -> 1 是允许的
1 -> 2 -> 1 -> 2 或者 1 -> 2 -> 3 -> 2 都是非法的。
输入数据的第一行为两个整数N M,分别表示节点个数和连接线路的条数(1<=N<=10000; 0<=M<=100000)。
接下去有M行,每行为两个整数 u 和 v,表示节点u 和 v 联通(1<=u,v<=N , u!=v)。
输入数据保证任意两点最多只有一条边连接,并且没有自己连自己的边,即不存在重边和自环。
1 2
2 3
1 3
1 2
2 3
3 1
1 4
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>using namespace std;const int MAXN=10000+5;#define INF 0x3f3f3f3fvector<int>G[MAXN];int ans;void dfs(int u,int fa,int len){//u为当前节点,fa为上一个结点,len为长度 if(len==3){ans++;return;}for(int i=0;i<G[u].size();i++){int v=G[u][i];if(v!=fa)//不为上一个结点,即不产生2个点徘徊的情况 {dfs(v,u,len+1);}}}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){ans=0;for(int i=0;i<=n;i++){G[i].clear();}for(int i=0;i<m;i++){int u,v;scanf("%d%d",&u,&v);G[u].push_back(v);G[v].push_back(u);}for(int i=1;i<=n;i++){if(G[i].size()>0){dfs(i,-1,0);}}printf("%d\n",ans);} return 0;}
PREV-19 九宫重排 搜索
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
123.46758
46758123.
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>using namespace std;const int MAXN=1000+5;#define INF 0x3f3f3f3f#define MOD 1000000007set<string>vis;//判重集合 int dist[4][2]={0,1,0,-1,1,0,-1,0};//方向向量 bool check(int x,int y)//是否越界 {if(x>=0&&x<3&&y>=0&&y<3){return true;}return false;}void init()//预处理每个位置能移动的下一个位置 {for(int i=0;i<3;i++){for(int j=0;j<3;j++){for(int k=0;k<4;k++){int x=i+dist[k][0];int y=j+dist[k][1];if(check(x,y)){G[i*3+j].push_back(x*3+y);}}}}}struct Node{//状态结果,保存当前的字符串[八数码的状态]和步数 string str;int step;};int bfs(string st,string ed){queue<Node>Q;Node start;start.str=st;start.step=0;Q.push(start);vis.insert(st);while(!Q.empty()){Node top,next;top=Q.front();Q.pop();if(top.str==ed){return top.step;}int index;for(int i=0;i<top.str.size();i++){//找到.的位置。 if(top.str[i]=='.'){index=i;break;}}for(int i=0;i<G[index].size();i++)//枚举.的移动方向 {next.step=top.step+1;next.str=top.str;swap(next.str[index],next.str[G[index][i]]);//移动后交换.和数字位置 if(vis.find(next.str)==vis.end())//判重 {Q.push(next);vis.insert(next.str);}}}return -1;}int main(){init();string st,ed;cin>>st;cin>>ed;cout<<bfs(st,ed)<<endl;return 0;}
PREV-21 回文数字
本题要求你找到一些5位或6位的十进制数字。满足如下要求:
该数字的各个数位之和等于输入的整数。
数字按从小到大的顺序排列。
如果没有满足条件的,输出:-1
499994
589985
598895
679976
688886
697796
769967
778877
787787
796697
859958
868868
877778
886688
895598
949949
958859
967769
976679
985589
994499
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>using namespace std;const int MAXN=10000+5;vector<int>five;vector<int>six;void init(){int num=0;for(int i=1;i<10;i++){for(int j=0;j<10;j++){for(int k=0;k<10;k++){num=i*10000+j*1000+k*100+j*10+i;five.push_back(num);num=i*100000+j*10000+k*1000+k*100+j*10+i;six.push_back(num);}}}sort(five.begin(),five.end());sort(six.begin(),six.end());}int sum_of_num(int n){int s=0;while(n){s+=n%10;n/=10;}return s;}int main(){init();int n;while(scanf("%d",&n)!=EOF){int cnt=0;for(int i=0;i<five.size();i++){if(sum_of_num(five[i])==n){printf("%d\n",five[i]);cnt++;}}for(int i=0;i<six.size();i++){if(sum_of_num(six[i])==n){printf("%d\n",six[i]);cnt++;}}if(cnt==0){printf("-1\n");}} return 0;}
PREV-22 国王的烦恼
如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。
现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。
接下来m行,每行三个整数a, b, t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。
1 2 2
1 3 2
2 3 1
3 4 3
第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。
第三天后3和4之间的桥不能使用,居民们会抗议。
对于50%的数据,1<=n<=500,1<=m<=10000;
对于100%的数据,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
思路:起初以为要各点都可达,发现不是,只要删掉的边的两个城市不可达就会发生暴动,以为是按时间顺序删除边的。那么我们可以反过来,起初全部边都有->按时间顺序的删除边==起初全部边都没有->按逆序顺序的添加边。 就是逆序使用并查集。注意下可能一天添加多条边但是别重复计算了。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>using namespace std;const int MAXN=10000+5;const int MAXM=100000+5;#define INF 0x3f3f3f3fstruct UF{private:int count;//不相交的集合数目int size[MAXN];//结点所在集合的大小,用于优化子树合并后的高度int path[MAXN];//对应根结点。public:void Init(int n){for (int i = 1; i <= n; i++){path[i] = i;size[i] = 1;}count=n;}bool connected(int p, int q)//是否在一个集合{return Find(p) == Find(q);}int Count(){return count;}int Find(int x)//找根结点 O(lgN){while (x != path[x]){// 将p节点的父节点设置为它的爷爷节点 path[x] = path[path[x]];x = path[x];}return x;}bool Union(int p, int q)//如果p,q本来就在同一个连通分量返回true; {//合并q,p集合int i = Find(p);int j = Find(q);if (i == j){return true;}// 将小树作为大树的子树 if (size[i] < size[j]){ path[i] = j; size[j] += size[i]; }else { path[j] = i;size[i] += size[j]; }return false;}};struct Edge{int u,v,t;};Edge e[MAXM];bool cmp(Edge a,Edge b){return a.t>b.t;}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<m;i++){scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].t);}sort(e,e+m,cmp);//按时间递减排序。 UF tmp;//并查集 tmp.Init(n);int ans=0,today=-1;for(int i=0;i<m;i++)//逆序进行并查集的合并 {if(tmp.Union(e[i].u,e[i].v)==false){//如果不在同一个连通分量,发生暴动 if(today!=e[i].t)//可能有一天多条路的情况 {ans++;}today=e[i].t;}}printf("%d\n",ans);} return 0;}
PREV-23 数字游戏
游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要说下一个数字2。再下面的一个同学要从上一个同学说的数字往下数两个数说出来,也就是说4。下一个同学要往下数三个数,说7。依次类推。
为了使数字不至于太大,栋栋和同学们约定,当在心中数到 k-1 时,下一个数字从0开始数。例如,当k=13时,栋栋和同学们报出的前几个数依次为:
1, 2, 4, 7, 11, 3, 9, 3, 11, 7。
游戏进行了一会儿,栋栋想知道,到目前为止,他所有说出的数字的总和是多少。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>using namespace std;typedef long long int LL;LL n,k,t;LL sum(LL a0,LL an,LL cnt){//求等差数列的和(a0:第一项 an:最后一项 cnt:项数 if(cnt%2){//注意乘法取模: (a*b)%c== (a%c * b%c)%creturn ((((a0+an)/2)%k)*(cnt%k))%k;}else{return (((cnt/2)%k)*((a0+an)%k))%k;}}int main(){while(scanf("%lld%lld%lld",&n,&k,&t)!=EOF){LL ans=1,st=1,ed=n;for(int i=1;i<t;i++){LL num=(1+sum(st,ed,ed))%k;ans+=num;ed+=n; //循环一次数组+n。 }printf("%lld\n",ans);}return 0;}
PREV-24 邮局
现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。
接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。
接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。
在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。
0 0
2 0
3 1
3 3
1 1
0 1
1 0
2 1
3 2
对于60%的数据,1<=m<=20;
对于100%的数据,1<=n<=50,1<=m<=25,1<=k<=10。
#include<iostream>#include<stdio.h>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>using namespace std;const int MAXN=10000+5;#define INF 0x3f3f3f3fstruct Point {double x,y;}peo[55],post[35];double dist(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double mindist,dis[35][55];//当前最优距离和,初始化每个人到每个邮局的距离 int n,m,k;int post_num[15],ans_post_num[15];//中间结果,最终结果 void dfs(int index,int cnt){//当前考虑邮局index,已经选了cnt个邮局 if(cnt==k)//已经选了k个邮局 {double sum_dist=0;for(int i=0;i<n;i++)//统计每个人离他最近的邮局的距离 {double min_i_dist=INF;for(int j=0;j<k;j++){min_i_dist=min(min_i_dist,dis[post_num[j]][i]);}sum_dist+=min_i_dist;}if(sum_dist<mindist)//更新最小值 {for(int i=0;i<k;i++){ans_post_num[i]=post_num[i];}mindist=sum_dist;}return;}for(int i=index+1;i<=m-k+cnt;i++){post_num[cnt]=i;dfs(i,cnt+1);}}void init(){mindist=INF*1.0;memset(dis,0,sizeof(dis));for(int i=0;i<m;i++){//计算每个人到每个邮局的距离 for(int j=0;j<n;j++){dis[i][j]=dist(post[i],peo[j]);}}}int main(){while(scanf("%d%d%d",&n,&m,&k)!=EOF){for(int i=0;i<n;i++){scanf("%lf%lf",&peo[i].x,&peo[i].y);}for(int i=0;i<m;i++){scanf("%lf%lf",&post[i].x,&post[i].y);}init();//初始化 for(int i=0;i<=(m-k);i++)//枚举起点 {post_num[0]=i;dfs(i,1);}for(int i=0;i<k;i++)//输出结果。 {printf("%d",ans_post_num[i]+1);if(i!=k-1){printf(" ");}else{printf("\n");}}} return 0;}
PREV-26 最大子阵
其中,A的子矩阵指在A中行和列均连续的一块。
接下来n行,每行m个整数,表示矩阵A。
-1 -4 3
3 4 -1
-5 -2 8
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。
#include<iostream>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<stdio.h>using namespace std;const int MAXN=500+5;int g[MAXN][MAXN],d[MAXN][MAXN];int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int maxval=-5005;memset(d,0,sizeof(d));for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&g[i][j]);d[i][j]=d[i-1][j]+g[i][j];//保存列的前缀和。 maxval=max(maxval,g[i][j]);}}/*for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cout<<d[i][j]<<' ';}cout<<endl;}*/int ans=0,tmp,flag=0;for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){tmp=0;//计算子矩阵 g[i][k]到g[j][k]的值 for(int k=1;k<=m;k++){int val=d[j][k]-d[i-1][k];if(tmp+val<val){tmp=val;}else{tmp+=val;}if(ans<tmp)//更新过结果,即存在子矩阵大于0 {ans=tmp;flag=true;}}}}if(flag)//如果不为全负数的矩阵 {printf("%d\n",ans);}else//矩阵全部元素小于等于0 {printf("%d\n",maxval);}}return 0;}
PREV-27 蚂蚁感冒
每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。
5 -2 8
-10 8 -20 12 25
思路:先分别存两边的蚂蚁的位置,两个蚂蚁相遇且同时调头方向行走可以看出两个蚂蚁擦肩而过继续按原来的方向行走,然后分类讨论,如果感冒的蚂蚁是朝右走的,那么朝左走并且位置大于感冒的蚂蚁的话都会被感染[然后因为方向相反并且位置大于它,所以肯定会相遇],然后,这些新感染感冒的蚂蚁[往左走的]当中位置最小的,将变成"新的起初感染的蚂蚁",然后找往右走的蚂蚁中,位置小于它的,这些也会被感染感冒。 同理可得开始感冒蚂蚁朝左。注意这些蚂蚁别重复计算了。
#include<iostream>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<stdio.h>using namespace std;vector<int>Left;vector<int>Right;int main(){int n;while(scanf("%d",&n)!=EOF){int fst=0;Left.clear(),Right.clear();for(int i=0;i<n;i++){int val;scanf("%d",&val);if(fst==0)//保存第一个蚂蚁的位置 {fst=val;}if(val>0){Right.push_back(val);}else{Left.push_back(val);}}int ans=1;//因为有一只蚂蚁已经感冒了,即第一只 if(fst>0)//分类讨论 ,大于0即感冒的蚂蚁朝右 {//那么往左走的位置大于它的蚂蚁都会被感染 int tmp=1000;for(int i=0;i<Left.size();i++){if(Left[i]*-1>=fst){ans++;tmp=min(tmp,Left[i]*-1);}}if(tmp!=1000)//如果有往走的蚂蚁被感染到。 {//那么这只蚂蚁就会感染往右走并且位置小于它的其他蚂蚁 for(int i=0;i<Right.size();i++){if(Right[i]<=tmp&&Right[i]!=fst){//注意别重复计算fst了,因为fst肯定在它左边,不然它不会 ans++;//被感染到。 }}}}else//同理 {int tmp=-1;for(int i=0;i<Right.size();i++){if(Right[i]<=fst*-1){ans++;tmp=max(tmp,Right[i]);}}for(int i=0;i<Left.size();i++){if(Left[i]*-1>=tmp&&Left[i]!=fst){ans++;}}}printf("%d\n",ans);}return 0;}
PREV-28 地宫取宝
地宫的入口在左上角,出口在右下角。
小明被带到地宫的入口,国王要求他只能向右或向下行走。
走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
1 2
2 1
1 2 3
2 1 5
记忆化思维DP,不太会写,看了别人的报告才写出来。 详细点这里 注意几个点,初始最大值应该是-1因为可能存在价值为0的位置。 所以数字需要maxv+1,
#include<iostream>#include<stdio.h>#include<cstring>#include<string>#include<algorithm>using namespace std;const int MAXN=55;const int MAXK=15;const int MAXV=15;const int MOD=1000000007;int v[MAXN][MAXN],dp[MAXN][MAXN][MAXK][MAXV];int n,m,k;int dfs(int x,int y,int kk,int maxv){//当前位置(x,y),手上有kk件宝物,这些宝物的最大值 if(dp[x][y][kk][maxv+1]!=-1){return dp[x][y][kk][maxv+1];}if(x==n-1&&y==m-1){//边界 if(kk==k){return dp[x][y][kk][maxv+1]=1;}else if(kk==k-1&&v[x][y]>maxv){return dp[x][y][kk][maxv+1]=1;}else{return dp[x][y][kk][maxv+1]=0;}}long long int cnt=0;if(y<m-1)//右边 {cnt=(cnt+dfs(x,y+1,kk,maxv))%MOD;//不拿 if(v[x][y]>maxv)//拿 {cnt=(cnt+dfs(x,y+1,kk+1,v[x][y]))%MOD;}} if(x<n-1)//下边 {cnt=(cnt+dfs(x+1,y,kk,maxv))%MOD;//不拿 if(v[x][y]>maxv)//拿 {cnt=(cnt+dfs(x+1,y,kk+1,v[x][y]))%MOD;}}return dp[x][y][kk][maxv+1]=cnt%MOD;}int main(){while(scanf("%d%d%d",&n,&m,&k)!=EOF){memset(dp,-1,sizeof(dp));for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&v[i][j]);}}dp[0][0][0][0]=dfs(0,0,0,-1);printf("%d\n",dp[0][0][0][0]);}return 0;}
PREV-31 小朋友排队
每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
3 2 1
对于30%的数据, 1<=n<=1000;
对于50%的数据, 1<=n<=10000;
对于100%的数据,1<=n<=100000,0<=Hi<=1000000。
#include<iostream>#include<stdio.h>#include<cstring>#include<string>#include<algorithm>using namespace std;#define Lowbit(x)(x&(-x)) const int MAXN=1000000+5;typedef long long int LL;LL c[MAXN],n,h[MAXN],l_max[MAXN],r_min[MAXN],cost[MAXN];//c:树状数组,n:人数,h:对应身高,l_max[i]:站在i左边并且身边比i高的人数//r_min[i]:站在i右边并且身高比i低的人数,cost:愤怒值 LL sum(int x){LL s=0;while(x>0){s+=c[x];x-=Lowbit(x);}return s;}void updata(int x,LL val){if(x==0){return;}while(x<=MAXN){c[x]+=val;x+=Lowbit(x);}}void init(){//初始化愤怒值。 cost[0]=0;for(int i=1;i<=100000;i++){cost[i]=cost[i-1]+i;}}int main(){while(scanf("%lld",&n)!=EOF){init();memset(c,0,sizeof(c));for(int i=1;i<=n;i++){scanf("%d",&h[i]);h[i]++;//防止出现h[i]=0的情况。因为树状数组不能有下标0的项 }LL ans=0;for(int i=n;i>=1;i--) {//逆序的求右边比它低的人数[逆序数] r_min[i]=sum(h[i]-1);updata(h[i],1);}memset(c,0,sizeof(c));for(int i=1;i<=n;i++){//顺序的求左边比它高的人数 l_max[i]=sum((MAXN-1))-sum(h[i]);updata(h[i],1);}for(int i=1;i<=n;i++){//计算总愤怒值 ans+=cost[l_max[i]+r_min[i]];}printf("%lld\n",ans);}return 0;}
每个小朋友都把自己的糖果分一半给左手边的孩子。
一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。
反复进行这个游戏,直到所有小朋友的糖果数都相同为止。
你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。
接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2)
2 2 4
#include<iostream>#include<stdio.h>#include<cstring>#include<string>#include<algorithm>using namespace std;const int MAXN=100+5;int val[MAXN],tmp[MAXN];//val:每个人的糖果数, tmp:每个人需要分给左边的人的糖果数 int main(){int n;while(scanf("%d",&n)!=EOF){for(int i=0;i<n;i++){scanf("%d",&val[i]);}int ans=0;while(1){int maxv=-1,minv=10000;//这n个人的糖果数目的最大值和最小值 for(int i=0;i<n;i++){maxv=max(maxv,val[i]);minv=min(minv,val[i]);}if(maxv==minv)//相等即说明每个人的糖果数是一样的。 {break;}for(int i=0;i<n;i++){tmp[i]=val[i]/2;//拿出一半的糖果准备分给左边的人 val[i]=val[i]/2;//拿出一半糖果后剩下多少糖果 }for(int i=0;i<n;i++)//开始分给左边的人 {if(i==n-1){ val[i]+=tmp[0];}else{val[i]+=tmp[i+1];}}for(int i=0;i<n;i++){//老师要补发的糖果 if(val[i]%2){val[i]+=1;ans++;}}}printf("%d\n",ans);}return 0;}
PREV-33 兰顿蚂蚁
兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。
平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。
蚂蚁的头部朝向为:上下左右其中一方。
蚂蚁的移动规则十分简单:
若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。
规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。
蚂蚁的路线是很难事先预测的。
你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。
接下来是 m 行数据。
每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。
接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
2 3 L 5
0 0 0
1 1 1
1 1 1
1 1 U 6
思路:按照题意模拟吧。 好像不需要考虑会不会越界的问题。 而且题目也没说越界要怎么处理。。
#include<iostream>#include<stdio.h>#include<cstring>#include<string>#include<algorithm>using namespace std;const int MAXN=100+5;int g[MAXN][MAXN],n,m;struct Node{int x,y,step;char s;Node(int a=0,int b=0,char c=0,int d=0):x(a),y(b),s(c),step(d){}};Node move(Node p,int temp){//按照题目移动,并返回移动后的状态[位置,步数,朝向] Node next;next.step=p.step-1;if(temp==1)//黑格{if(p.s=='U'){next.x=p.x; next.y=p.y+1; next.s='R';}else if(p.s=='D'){next.x=p.x; next.y=p.y-1; next.s='L';}else if(p.s=='L'){next.x=p.x-1;next.y=p.y;next.s='U';}else{next.x=p.x+1;next.y=p.y;next.s='D';}g[p.x][p.y]=0;}else{if(p.s=='U'){next.x=p.x; next.y=p.y-1; next.s='L';}else if(p.s=='D'){next.x=p.x; next.y=p.y+1; next.s='R';}else if(p.s=='L'){next.x=p.x+1;next.y=p.y;next.s='D';}else{next.x=p.x-1;next.y=p.y;next.s='U';}g[p.x][p.y]=1;} return next;}int main(){while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&g[i][j]);}}Node start;scanf("%d %d %s %d",&start.x,&start.y,&start.s,&start.step);while(start.step){start=move(start,g[start.x][start.y]);}printf("%d %d\n",start.x,start.y);}return 0;}
- 备战蓝桥杯--历届试题题解
- 【蓝桥杯】 历届试题 题解
- 蓝桥杯历届试题题解1
- 蓝桥杯历届试题题解2
- 蓝桥杯 历届试题 带分数
- 蓝桥杯2014-历届试题
- 蓝桥杯 历届试题 邮局
- 蓝桥杯-历届试题-带分数
- 蓝桥杯历届试题
- 蓝桥杯历届试题 带分数
- 蓝桥杯 历届试题 带分数
- 蓝桥杯 历届试题 带分数
- 蓝桥杯 历届试题 带分数
- 蓝桥杯 历届试题 振兴中华
- 蓝桥杯 历届试题 城市建设
- 蓝桥杯 历届试题 调和级数
- 蓝桥杯 历届试题 带分数
- 蓝桥杯 历届试题 敢死队
- 如何使用swiper
- C++中Vector的erase()操作以及与remove的区别
- 如何视觉隐藏网页内容,只让它们在屏幕阅读器中可用?
- SQL server 基础
- JSP中播放提示声音
- 备战蓝桥杯--历届试题题解
- 二叉树, 二叉查找树,二分查找算法
- 227. Basic Calculator II
- map 详细用法(常看看哦)
- 20140816题目小节
- pow()
- HTTP头的Expires与Cache-control
- 优先队列
- Java虚拟机结构