第十二届蓝桥杯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;
}

posted @ 2021-04-29 09:19  一个经常掉线的人  阅读(180)  评论(0)    收藏  举报