蓝桥杯刷题 历届试题 (PREV-1——PREV-10)
PREV-1 核桃的数量
#include<bits/stdc++.h> using namespace std; int main() { int a,b,c,d; cin>>a>>b>>c; d=(a*b/__gcd(a,b)); cout<<c*d/__gcd(d,c); }
PREV-2 打印十字图
#include <stdio.h> int a[150][150]; //将这个图划分为多个具有相同规律的部分 然后进行遍历就行 //图 int main() { int N; int ROW,COL; int min; int i,j; scanf("%d",&N); ROW = COL = 9 + (N-1)*4; min = ROW / 2; for(i = 0; i <= min; i+=2) // 处理上下的 { for(j = i + 2; j < ROW - (i+2); j++) { a[i][j] = 1; a[ROW - i - 1][j] = 1; } } for(j = 2; j <= min; j+=2) //左右的竖线 { for(i = j - 2; i < j + 1; i++) { a[i][j] = 1; a[i][COL - j - 1] = 1; a[ROW - i - 1][j] = 1; a[ROW - i - 1][COL - j - 1] = 1; } } for(i = 2; i <= min; i += 2) { for(j = i - 2; j < i + 1; j++) { a[i][j] = 1; a[i][COL - j - 1] = 1; a[ROW - i - 1][j] = 1; a[ROW - i - 1][COL - j - 1] = 1; } } for(j = 0; j < min; j += 2)//左右长的竖线 { for(i = j+2; i < ROW - (j + 2); i++) { a[i][j] = 1; a[i][ROW - j - 1] = 1; } } for(i = 0; i < ROW; i++) { for(j = 0; j < ROW; j++) printf("%c", a[i][j] ? '$' : '.'); putchar('\n'); } return 0; }
PREV-3 带分数
dfs求全排列,然后判断这个排列是否能够组成带分数即可
小技巧是不需要完全按照格式模拟,怎么方便怎么求
#include<bits/stdc++.h> using namespace std; int s[15],sum=0,t; void pd() { int a,b,c; for(int i=1;i<=9;i++) { a=0; for(int j=1;j<=i;j++) { a=a*10+s[j]; } if(a<t) { for(int j=(9-i)/2+i;j<=8;j++) { b=0; c=0; for(int h=i+1;h<=j;h++) b=b*10+s[h]; for(int h=j+1;h<=9;h++) c=c*10+s[h]; if(b%c==0&&a+b/c==t) sum++; } } } } void dfs(int start,int end) { if(start==end) { pd(); } else { for(int i=start;i<=end;i++) { swap(s[i],s[start]); dfs(start+1,end); swap(s[i],s[start]); } } } int main() { cin>>t; for(int i=1;i<=9;i++) { s[i]=i; } dfs(1,9); cout<<sum<<endl; }
PREV-4 剪格子
从左上角dfs即可
#include<bits/stdc++.h> using namespace std; int n,m,mp[15][15],sum=0,t=0,f[2][4]={0,0,1,-1,1,-1,0,0},anss=200,vis[15][15]; void dfs(int x,int y,int lsum) { if(lsum==sum/2) { if(t<anss) { anss=t; } return; } else if(lsum>sum/2) { return; } for(int i=0;i<4;i++) { int xx=x+f[0][i]; int yy=y+f[1][i]; if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&vis[xx][yy]==0) { vis[xx][yy]=1; t+=1; dfs(xx,yy,lsum+mp[xx][yy]); t-=1; vis[xx][yy]=0; } } } int main() { cin>>m>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>mp[i][j]; sum+=mp[i][j]; vis[i][j]=0; } } if(sum%2!=0) { cout<<'0'<<endl; return 0; } vis[1][1]=1; t+=1; dfs(1,1,mp[1][1]); if(anss==200) { cout<<0<<endl; } else { cout<<anss<<endl; } }
PREV-5 错误票据
#include<bits/stdc++.h> using namespace std; map<int,int>mp; int a[105],n,m,cnt=0,x; int main() { cin>>n; while(scanf("%d",&x)!=EOF) { if(mp[x]==1) { n=x; } else { a[cnt]=x; mp[a[cnt]]=1; cnt++; } } sort(a,a+cnt); for(int i=1;i<cnt;i++) { if(a[i]-a[i-1]!=1) { m=a[i]-1; } } cout<<m<<' '<<n<<endl; }
PREV-6 翻硬币
将两个序列不同的位置设为1,相同的设为0,则两个1的下标差为改正这两个位置的最小次数,对于多对1,按顺序遍历即可
#include<bits/stdc++.h> using namespace std; int main() { int a[105],anss=0,l=-1; string s1,s2; cin>>s1>>s2; for(int i=0;i<s1.length();i++) { if(s1[i]!=s2[i]) a[i]=1; else a[i]=0; } for(int i=0;i<s1.length();i++) { if(a[i]==1) { if(l==-1) { l=i; } else { anss+=i-l; l=-1; } } } cout<<anss<<endl; }
PREV-7 连号区间数
如果区间两端下标的差正好等于区间最大值-最小值,那么为连续区间
#include<bits/stdc++.h> using namespace std; int n,a[50005],s[50005],anss=0,i,l,r; int main() { cin>>n; for(i=0;i<n;i++) { cin>>a[i]; s[i]=1; } for(l=0;l<n;l++) { int maxn=a[l]; int minn=a[l]; for(r=l+1;r<n;r++) { maxn=max(maxn,a[r]); minn=min(minn,a[r]); if(maxn-minn==r-l) s[l]++; } anss+=s[l]; } cout<<anss<<endl; }
PREV-8 买不到的数目
动态规划,遍历的最大边界是两个数的最小公倍数
#include<bits/stdc++.h> using namespace std; int n,m,vis[1000005],anss=1,maxn; int main() { cin>>n>>m; maxn=n*m/__gcd(n,m); memset(vis,0,sizeof(vis)); vis[n]=1; vis[m]=1; for(int i=1;i<maxn;i++) { if(vis[i]) { vis[i+n]=1; vis[i+m]=1; } else { anss=i; } } cout<<anss<<endl; }
PREV-9 大臣的旅费
求树的直径,只需进行两次bfs,一次bfs找到直径的一个端点,第二次bfs从这个端点出发,找到对应的另个端点
#include<bits/stdc++.h> using namespace std; queue<int>q; vector<int>lb[10005]; int mp[10005][10005],vis[10005],a,b,x,n,anss=0,end,end2; int getlong(int x) { int sum=0; for(int i=1;i<=x;i++) { sum+=i+10; } return sum; } void bfs() { while(!q.empty()) { int now = q.front(); q.pop(); int step = q.front(); q.pop(); vis[now]=1; if(anss<step) { end=now; anss=step; } for(int i=0;i<lb[now].size();i++) { if(vis[lb[now][i]]==0) { q.push(lb[now][i]); q.push(step+mp[lb[now][i]][now]); } } } } void bfs2() { while(!q.empty()) { int now = q.front(); q.pop(); int step = q.front(); q.pop(); vis[now]=1; if(anss<step) { end2=now; anss=step; } for(int i=0;i<lb[now].size();i++) { if(vis[lb[now][i]]==0) { q.push(lb[now][i]); q.push(step+mp[lb[now][i]][now]); } } } } int main() { cin>>n; for(int i=1;i<n;i++) { cin>>a>>b>>x; mp[a][b]=x; mp[b][a]=x; vis[a]=0; vis[b]=0; lb[a].push_back(b); lb[b].push_back(a); } q.push(1); q.push(0); bfs(); memset(vis,0,sizeof(vis)); //cout<<end<<endl; anss=0; q.push(end); q.push(0); bfs2(); cout<<getlong(anss)<<endl; //cout<<end2<<endl; }
PREV-10 幸运数
直接暴力模拟,没想到就能过
#include<bits/stdc++.h> using namespace std; int n,m,lists[1000005],sum,cnt,i,start,fm,anss=0; int main() { cin>>m>>n; start = 2; sum=2*n; for(i=1;i<=2*n;i++) { //alive[i]=1; lists[i]=i; } while(1) { fm=lists[start]; if(fm>=n) break; cnt=0; for(i=0;i<start;i++) { lists[cnt++]=lists[i]; } for(i=start;i<sum;i++) { if(i%fm==0) continue; else lists[cnt++]=lists[i]; } sum = cnt; start++; if(fm==2) start--; } for(i=1;i<sum;i++) { if(lists[i]>m&&lists[i]<n) anss++; if(lists[i]>=lists[i+1]) break; } cout<<anss<<endl; }