第十二届蓝桥杯C++ B组(不断更新ing)
A: 空间

1MB=1024KB 1KB=1024B 1B=8b
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int main(){
cout<<256*1024*1024/4;
return 0;
}
// freopen("testdata.in", "r", stdin);
B: 卡片

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int nums[10];
int flag;
int fun(int i){
int flag=1;
string s=to_string(i);
for(auto i:s){
int temp=i-'0';
nums[temp]--;
if(nums[temp]<0){
flag=0;
break;
}
}
return flag;
}
int main(){
for(int i=0;i<=9;i++) nums[i]=2021;
for(int i=1;;i++){
if(!fun(i)){
cout<<i-1<<endl;
break;
}
}
return 0;
}
// freopen("testdata.in", "r", stdin);
C 直线

直线y=kx+b 通过k和b来判断是不是不同的直线
根据题意会有20条斜率不存在的直线,在编程时不考虑他们最后答案加上20即可
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<cmath>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=200005;
int n;
struct Line{
double k,b;
}l[N];
//自定义排序
bool cmp(Line &a,Line &b){
if(a.k!=b.k){
return a.k<b.k;
}
else return a.b<b.b;
}
//判断两个浮点数是不是一样
int isfun(double a,double b){
return fabs(a-b)>1e-8;
}
int main(){
for(int x1=0;x1<20;x1++){
for(int y1=0;y1<21;y1++){
for(int x2=0;x2<20;x2++){
for(int y2=0;y2<21;y2++){
if(x1!=x2){//不能一样
double k=(double)(y2-y1)/(x2-x1);
double b=y1-k*x1;
l[n++]={k,b};
}
}
}
}
}
sort(l,l+n,cmp);
int res=1;
for(int i=1;i<n;i++){
if(isfun(l[i].k,l[i-1].k) || isfun(l[i].b,l[i-1].b))//判断和上一条线是不是同一条
res++;
}
cout<<res+20;
return 0;
}
// freopen("testdata.in", "r", stdin);
D货物摆放

答案一定是在约数里面找,先求它的约数然后枚举
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
vector<LL> d;
LL n;
int main(){
cin>>n;
for(LL i=1;i*i<=n;i++){
if(n%i==0){
d.push_back(i);
if(i!=n/i){//n整除 i 就必整除 n/i;
d.push_back(n/i);
}
}
}
int ans=0;
for(auto a:d){
for(auto b:d){
for(auto c:d){
if(a*b*c==n){
ans++;
}
}
}
}
cout<<ans<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
E路径

裸最短路问题。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
#include<cmath>
using namespace std;
typedef long long LL;
//最小公倍数 = 两数乘积 / 最大公约数
int gcd(int a,int b){
if(!b) return a;
else return gcd(b,a%b);
}
int lcm(int a,int b){
return (a*b)/gcd(a,b);
}
const int N=1e5+5;
int h[N],ne[N],e[N],w[N],idx;
int dist[N];
bool st[N];
void add(int a,int b,int c){
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
int fun(){
memset(dist,0x3f,sizeof dist);
dist[1]=0;
queue<int>q;
st[1]=true;
q.push(1);
while(q.size()){
int t=q.front();
q.pop();
st[t]=false;
for(int i=h[t];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>dist[t]+w[i]){
dist[j]=dist[t]+w[i];
if(!st[j]){
q.push(j);
st[j]=true;
}
}
}
}
}
int main(){
memset(h,-1,sizeof h);
for(int i=1;i<=2021;i++){
for(int j=i+1;j<=2021;j++){
if(fabs(i-j)<=21){
int c=lcm(i,j);
add(i,j,c);
add(j,i,c);
}
}
}
fun();
cout<<dist[2021]<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
时间显示
https://www.acwing.com/problem/content/3419/
简单的模拟,比赛一定要看清楚题目,做了半天才发现给毫秒。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
LL n;
int h,m,s;
int main(){
cin>>n;
n/=1000;//毫秒变秒
n%=86400;//一天有86400秒,通过%去除多余的运算
while(n--){
s++;
if(s==60){
s=0;
m++;
}
if(m==60){
m=0;
h++;
}
if(h==24){
h=0;
s=0;
m=0;
}
}
printf("%02d:%02d:%02d",h,m,s);
return 0;
}
// freopen("testdata.in", "r", stdin);
砝码称重
https://www.acwing.com/problem/content/3420/
背包DP做法可解
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=110,M=200010,B=M/2;
int n,m;
int w[N];
bool f[N][M];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",w+i);
m+=w[i];
}
f[0][B]=true;
for(int i=1;i<=n;i++){
for(int j=-m;j<=m;j++){
f[i][j+B]=f[i-1][j+B];
if(j-w[i]>=-m) f[i][j+B]|=f[i-1][j-w[i]+B];
if(j+w[i]<=m) f[i][j+B]|=f[i-1][j+w[i]+B];
}
}
int res=0;
for(int j=1;j<=m;j++){
if(f[n][j+B]) res++;
}
cout<<res<<endl;
return 0;
}
// freopen("testdata.in", "r", stdin);
杨辉三角形
https://www.acwing.com/problem/content/3421/
比赛现场用两行数组不断模拟了,只能拿部分分
网上题解
对于3000*3000的部分直接暴力
然后我们容易发现,对于C(3000,3) 已经超过了1e9,也就是在行数大于3000的每一行,我们只需要枚举C(n,2)即可,而n达到1e5的时候,C(n,2)就超过了1e9。
如果前面都没有的话,那么说明只能在C(n,1)的位置出现。计算答案的话,因为杨辉三角每一行的个数都比上一行多一个,所以等差数列求和即可,注意结果会炸int。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+50;
int main(){
int n;cin>>n;
if(n==1){
cout<<1;
return 0;
}
for(int i=2;i<=3000;i++){
ll now=1;
for(ll j=1;j<=i;j++){
now=now*(i-j+1);
now/=j;
if(now>n) break;
if(now==n){
ll cnt=1ll*i*(i+1)/2;
cout<<cnt+j+1;
return 0;
}
}
}
for(int i=3000;i<=100000;i++){
ll cnt=1ll*i*(i-1)/2;
if(cnt==n){
cout<<1ll*i*(i+1)/2+3;
return 0;
}
if(cnt>n) break;
}
cout<<1ll*(n+1)*n/2+2<<endl;
return 0;
}

浙公网安备 33010602011771号