第十二届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组 填空题

在这里插入图片描述

256*1024*1024/4 = 67,108,864

在这里插入图片描述
答案 3181

/*模拟一下结果就出来了*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int a[10];
int main()
{
	for(int i=0;i<10;i++)
	a[i] = 2021;
	
	int res = 1;
	bool flag = true;
	int num;
	
	while(flag)
	{
		int r = res;
		while(r)
		{
			num = r % 10;
			if(!a[num]) //没有数字 
			{
				flag = false;
				break;
			}
			a[num]--;
			r /= 10;
		}
		if(flag)
		res++;
	}
	
	cout<<res-1<<endl;
	return 0;
}


在这里插入图片描述

/*
一条直线就是y = kx + b
我们区分直线的标志就是斜率 k 和截距 b
设两个点是(x1,y1),(x2,y2)
k = (y2 - y1) / (x2 - x1)
b = -k*x1 + y1
我的思路是一个k对应一个b的set集合
k是好求的,关键是b的精度问题
最后把斜率不存在以及斜率为0的直线加起来
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <map>

using namespace std;

map<double,set<double> >mp;

int main()
{
	int xx = 19,yy = 20;
	for(int i=0;i<=xx;i++)
	{
		for(int j=0;j<=yy;j++) //第一个点 
		{
			for(int k=0;k<=xx;k++)
			{
				for(int l=0;l<=yy;l++) //第二个点 
				{
					if(i == k || j == l) continue;
					
					double x = (double)(i - k);
					double y = (double)(j - l);
					double z = y * 1.0 / x;  
				//	double b = (double)(j - z*i);  //这样记录 b 结果是 47753,我比赛用的是这个,可能错了!


				//  k = (y2 - y1) / (x2 - x1)把这个表达式代入b = -k*x1 + y1在化简
					double b = ((double)(k*j) - (double)(i*l)) / (i-k);   //这个结果是 40257 好像这样更对 
					mp[z].insert(b); 
				}
			}
		}
	}
	
	int res = 0;
	map<double,set<double> >::iterator it = mp.begin();
	
	for(;it!=mp.end();it++)
	{
		res += it->second.size();
	}
	
	cout<<res + xx + 1 + yy + 1<<endl;
	return 0;
}

在这里插入图片描述
答案是2430

/*没写出来...我的思路是分解质因子,然后排列组合,但是有更暴力的方法直接求因子,然后三重循环遍历因子就出来了*/

//这是求出的质因子
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cmath>

using namespace std;

map<int,int>mp;
typedef long long ll;
int main()
{
	ll num = 2021041820210418;
	
	for(int i=2;i<100000;i++)
	{
		if(num % i == 0)
		{
			while(num % i == 0)
			{
				num /= i;
				mp[i]++;
			}
		}
	}
	if(num != 0)
	mp[num]++;
	
	map<int,int>::iterator it = mp.begin();
	for(;it != mp.end();it++)
	{
		cout<<it->first<< " " <<it->second<<endl;
	}
	return 0;
}

在这里插入图片描述

/*两重循环就出来了......太暴力了*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

typedef long long ll;
ll num = 2021041820210418;
ll arr[100000];

int main()
{
    int index = 0;
    for(int i=1;i<=sqrt(num);i++)
    {
        if(num % i == 0)
        {
            arr[index++] = i;
            arr[index++] = num / i;
        }
    }    

    int res = 0;
    for(int i=0;i<index;i++){
        for(int j=0;j<index;j++)
        if(num % (arr[i] * arr[j]) == 0)
        res++;
    }

    cout<<res<<endl;
    return 0;
}

在这里插入图片描述
答案 10266837

/*直接上Dijkstra*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;

const int maxn = 2022;
int vel[maxn][maxn];
vector<int>g[maxn];
bool sign[maxn];
int dis[maxn];

struct node{
	int n_dis;
	int id;
	bool operator < (const node &a) const{
		return a.n_dis < n_dis;
	}
}; 
int gcd(int a,int b)
{
	if(b == 0) return a;
	return gcd(b,a%b);
}
void dijkstra(int s)
{
	for(int i=1;i<maxn;i++)
	dis[i] = 1000000000,sign[i] = false;
	
	dis[s] = 0;
	priority_queue<node>q;
	node h;
	h.id = 1,h.n_dis = 0;
	q.push(h);
	
	while(!q.empty())
	{
		node u = q.top();
		q.pop();
		
		if(sign[u.id]) continue;
		sign[u.id] = true;
		
		
		for(int i=0;i<g[u.id].size();i++)
		{
			int j = g[u.id][i];

			if(sign[j]) continue;
			
			if(vel[u.id][j] + u.n_dis < dis[j])
			{
				dis[j] = h.n_dis = vel[u.id][j] + u.n_dis;
				h.id = j;
				q.push(h);
			}
		}
	}
}
int main()
{
	//建图
	for(int i=1;i<maxn;i++)
	{
		for(int j=1+i;j<maxn;j++)
		{
			if(abs(i-j) <= 21)
			{
				int num = gcd(i,j);
				g[i].push_back(j),g[j].push_back(i);
				vel[i][j] = vel[j][i] = i*j/num;
			}
		}
	}
	
	/*
	for(int i=1;i<maxn;i++)
	cout<<g[i].size()<<endl;
	*/
	dijkstra(1);
	
	for(int i=1;i<maxn;i++)
	cout<<dis[i]<<endl;
	
	cout<<"2021 = "<<dis[2021]<<endl;
	return 0;
}

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

译制片~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值