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

试题 A: 空间

在这里插入图片描述

5分 67108864

void run()
{
	ll ans = 256*1024*1024/4;
	cout << ans << endl;
}

试题 B: 卡片

在这里插入图片描述

5分 3181

void run()
{
	int i, j;
	for (i = 0; i <= 9; i ++ ) st[i] = 2021;
	for (i = 0; ; i ++ ) {
		if(0 <= i && i < 10) {
			st[i] -= 1;
			if(st[i] == 0) {
				cout << i;
				break;
			}
		}
		else if(10 <= i &&i < 100) {
			int a = i%10, b = i/10%10;
			st[a] -= 1, st[b] -= 1;
			if(st[a] == 0 || st[b] == 0) {
				cout << i;
				break;
			}
		}
		else if(100 <= i && i < 1000) {
			int a= i%10, b= i/10%10, c = i/100%10;
			st[a] -= 1, st[b] -= 1, st[c] -= 1;
			if(st[a] == 0 ||st[b] == 0 || st[c] == 0) {
				cout << i;
				break;
			}
		}
		else if(1000<= i && i < 10000){
			int a= i%10, b= i/10%10, c = i/100%10, d = i/1000%10;
			st[a] -= 1, st[b] -= 1, st[c] -= 1, st[d] -= 1;
			if(st[a] == 0 ||st[b] == 0 || st[c] == 0 || st[d] == 0)  {
				cout << i;
				break;
			}
			
		}
		else {
			for (j = 0; j <= 9; j ++ ) cout << st[i] << ' ';
			break;
		}
	}
}

这样写会简单一些

#include <algorithm>
#include <cstring>
#include <iostream>

using namespace std;
int s[10];

bool check(int x) {
  while (x) {
    int t = x % 10;
    x = x / 10;
    if (--s[t] < 0) return false;
  }
  return true;
}

int main() {
  for (int i = 0; i < 10; i++) s[i] = 2021;
  for (int i = 1;; i++) {
    if (!check(i)) {
      //检查该数是否已经用完,不够用即最后一个数为所求的数
      cout << i - 1 << endl;
      return 0;
    }
  }
}

试题 C: 直线

在这里插入图片描述

0分

typedef pair<double, double> PII;

set<PII> st;
void run() // 47753 始终多一些,之前是因为整除的原因
{
	double i,j, x, y;
	int n = 20, m = 21;
	for (i = 0; i < n; i ++ ) {
		for (j = 0; j < m; j ++ ) {
			
			for (x = 0; x < n; x ++ ) {
				for (y = 0; y < m;  y ++ ) {
					if(i == x && j == y) continue;
					double k, b;
					if(x-i == 0) continue;
					else if(y-j == 0) continue;
					else k = (y-j)*1.0/(x-i),b = y - k*x; // 除0
//					deb2(k, b);
					st.insert({k, b});
				}
			}
		}
	}
	
	cout << st.size() + n+m;
}
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++ )
#define deb2(x, y) cout << #x << '=' << x << ',' << #y << '=' << y <<endl
#define deb3(x, y, z) cout << #x <<'=' << x << ',' << #y << '=' << y << ',' << #z << '=' << z << endl
using namespace std;

const int N = 2e5 + 10, mod = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<pii, int> PII;
set<PII> st;

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a%b);
}
void run() // 40257 
{
	int x1, y1, x2, y2;
	int n = 20, m = 21;
	for (x1 = 0; x1 < n; x1 ++) {
		for (y1 = 0; y1 < m; y1 ++) {
			for (x2 = 0; x2 < n; x2 ++ ) {
				for (y2 = 0; y2 < m; y2 ++ ) {
					if(x1 == x2 && y1 == y2) continue;
					int a = y2-y1;
					int b = x1-x2;
					int c = y1*x2-y2*x1;
					int m = gcd(gcd(a, b), c);
					a /= m, b /= m, c /= m;
					st.insert({{a, b}, c});
				}
			}
		}
	}
	cout << st.size() << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    cout << fixed; cout.precision(18);
    int T = 1;
    //cin >> T;
    
    while(T -- ) run();
    
}

试题 D: 货物摆放

在这里插入图片描述

10分

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++ )
#define deb2(x, y) cout << #x << '=' << x << ',' << #y << '=' << y <<endl

using namespace std;

const int N = 2e5 + 10, mod = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;

int a[N];

void run()
{
	ll n =  2021041820210418;
	vector<ll> q;
	
	ll i; //怎么我悟不出: n一定是由n的因子组成的
	for (i = 1; i *i <= n; i ++ ) {
		if(n % i == 0) {
			q.push_back(i);
			if(i*i != n) q.push_back(n/i); 
		}
	}
	
	ll res = 0;
	for (auto a : q) {
		for (auto b : q) {
			for (auto c : q) {
				if(a*b*c == n) res += 1;
			}
		}
	}
	
	cout << res << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    cout << fixed; cout.precision(18);
    int T = 1;
    //cin >> T;
    
    while(T -- ) run();
    
}

试题 E: 路径

在这里插入图片描述

10266837 flody可以跑耶耶耶耶耶耶15分到手

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++ )
#define deb2(x, y) cout << #x << '=' << x << ',' << #y << '=' << y <<endl

using namespace std;

const int N = 2e5 + 10, mod = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;

int g[3000][3000];
int n = 2021;

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a%b);
}
void run()
{
	memset(g, 0x3f, sizeof g);
	int i, j;
	for (i = 1; i <= n; i ++ ) {
		for (j = max(1,i-21); j <= min(n, i+21); j ++ ) { // j
			int t = gcd(i, j);
			g[i][j] = g[j][i] = i*j/t;
		}		
	}
	int k;
	for (k = 1; k <= n; k ++ )
	for (i = 1; i <= n; i ++ )
	for (j = 1; j <= n; j ++ ) {
		if(g[i][j] > g[i][k] + g[k][j])
			g[i][j] = g[i][k] + g[k][j];
	}
	
	cout << g[1][n] << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    cout << fixed; cout.precision(18);
    int T = 1;
    //cin >> T;
    
    while(T -- ) run();
    
}

用dij写速度也不快

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++ )
#define deb2(x, y) cout << #x << '=' << x << ',' << #y << '=' << y <<endl

using namespace std;

const int N = 2e5 + 10, mod = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;

int g[3000][3000];
bool st[2030];
int d[2030];
int n = 2021;

int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a%b);
}

void dij() {
	d[1] = 0; // 初始化错误
	priority_queue<PII> q;
	q.push({0, 1});
	while(!q.empty()) {
		PII t = q.top(); q.pop();
		int u = t.second;
		if(st[u] == 1) continue;
		st[u] == 1;
		
		for (int i = 1; i <= n; i ++ ) {
			if(i == u) continue;
			if(d[i] > d[u] + g[u][i])  {
				d[i] = d[u] + g[u][i];
				q.push({d[i], i});
			}
		}
	}
}
 
void run()
{
	memset(g, 0x3f, sizeof g);
	memset(d, 0x3f, sizeof d);
	int i, j;
	for (i = 1; i <= n; i ++ ) {
		for (j = max(1,i-21); j <= min(n, i+21); j ++ ) { // j
			int t = gcd(i, j);
			g[i][j] = g[j][i] = i*j/t;
		}		
	}
	dij();
	cout << d[n] << endl;
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    cout << fixed; cout.precision(18);
    int T = 1;
    //cin >> T;
    
    while(T -- ) run();
    
}

试题 F: 时间显示

在这里插入图片描述

怎么办,这道题显得我很弱智,我没了,我是题目理解怪物吧

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++ )
#define deb2(x, y) cout << #x << '=' << x << ',' << #y << '=' << y <<endl

using namespace std;

const int N = 2e5 + 10, mod = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;

int m[] = {0, 31, 28, 31, 20, 31, 30, 31, 31, 30, 31, 30, 31};

void run()
{
	ll x; cin >> x;
	int k = 24*3600;
	int i, j, d;
	x/= 1000; // 我服了,题目给的毫秒
	for (i = 1970; i <= 2020; i ++) { // 我天,我是题目理解怪物吗?
		m[2] = 28;
		if(i % 4 == 0 && i % 100 || i % 400 == 0) m[2] = 29;
		for (j = 1; j <= 12; j ++ ) {
			for (d = 1; d <= m[j]; d ++ ) {
				deb2(x, k);
				if(x >= k) x -= k;
				else {
					int h = x / 3600;
					int m = x / 60 % 60;
					int s = x % 60;
					printf("%02d:%02d:%02d", h, m, s);
					return ;
				}
			}
		}		
	}

}


signed main()
{
//    ios::sync_with_stdio(false), cin.tie(0);
//    cout << fixed; cout.precision(18);
    int T = 1;
    //cin >> T;
    
    while(T -- ) run();
    
}
void run()
{
	ll x; cin >> x; x /= 1000;
	int k = 24*3600;
	x %= k;
	int h = x /3600;
	int m = x / 60 % 60;
	int s = x % 60;
	printf("%02d:%02d:%02d", h, m, s);

}

set遍历的方法

#include<bits/stdc++.h>
using namespace std;

set<int> s;
int a[100];

int main()
{
    s.clear();
    int k = 9;
    int cnt = 0;
    for(int i = 1;i <= 10;++i) s.insert(i*k%7);
    // for(auto it = s.begin();it != s.end();it++) {
    //     a[cnt++] = *it;
    // }
    for(set<int>::iterator it = s.begin();it != s.end();it++) {
        a[cnt++] = *it;
    }
    for(int i = 0;i < cnt;++i) {
        cout << a[i] << ' ';
    }
    cout << endl;
}

试题 G: 砝码称重

在这里插入图片描述在这里插入图片描述

正解,注意数组要开大一点,不然取min在这里插入图片描述

#include <iostream>
using namespace std;

const int N = 110, M = 2e5 + 10;
bool f[N][M];
int w[N];

int main()
{
  // 请在此输入您的代码
    int n; cin >> n;
    int i, j, sum = 0;
    for (i = 1; i <= n; i ++ ) cin >> w[i], sum += w[i];
    f[0][0] = 1;
    for (i = 1; i <= n; i ++ ) {
        for (j = 0; j <= sum; j ++ ) {
            f[i][j] = f[i-1][j] + f[i-1][abs(j-w[i])] 
                    + f[i-1][j+w[i]];
            // cout << f[i][j] << ' ';
        }
        // cout << endl;
    }

    int ans = 0;
    for (i = 1; i <= sum; i ++ ) if(f[n][i]) ans += 1;
    cout << ans << endl;
    return 0;
}

试题 H: 杨辉三角形

在这里插入图片描述

😊😍y总这个方法好用,这是估算的方法
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

int n;
/*
    组合数和杨辉三角:第i行第j列的数都是组合数C(i, j) (i,j从0开始)
        C(n, 1) = n --> 对应从左向右看斜着的第二列! ---> 一定有解
    由于杨辉三角左右对称(C(a, b) == C(a, a-b)),又由于找第一次出现,因此一定在左边,右边可以直接删掉!

            1  ---> C(0, 0)
          1 
        1   2  ---> C(2, 1)
      1   3                             ---> C(2n, n)
    1   4   6  ---> C(4, 2)
  1   5   10
1   6   15  20 ---> C(6, 3)

    n最大1e9,C(34, 17) > 1e9, C(32, 16) < 1e9,因此只要枚举前16个斜行即可!


    性质:
        1. 每一斜行从上到下递增
        2. 每一横行从中间到两边依次递减

    因此我们直接从中间对称轴倒序二分找起即可!

        C(r, k)对应的顺序值为:(r + 1) * r / 2 + k + 1

        二分的左右端点:l:2k,r:max(n, l)
            右端点一定不能比左端点小!
            特例:否则当n=1时,会出问题!

*/
// C(a, b) = a!/b!(a-b)! = a * (a-1) .. b个 / b!
LL C(int a, int b){
    LL res = 1;
    for(int i = a, j = 1; j <= b; i --, j ++){
        res = res * i / j;
        // 大于n已无意义,且防止爆LL
        if(res > n) return res;
    }
    return res;
}

bool check(int k){
    // 二分该斜行,找到大于等于该值的第一个数
    // 左边界2k,右边界为max(l, n)取二者最大即可!
    int l = 2 * k, r = max(n, l);
    while(l < r){
        int mid = l + r >> 1;
        if(C(mid, k) >= n) r = mid;
        else l = mid + 1;
    }
    if(C(r, k) != n) return false;
    // C(r, k)的从0开始的顺序!
    cout << 1ll * (r + 1) * r / 2 + k + 1 << endl;
    return true;
}

int main(){
    cin >> n;
    // 从第16斜行枚举即可!
    for(int k = 16; ; k --)
        if(check(k)) break;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值