[Blue Bridge Cup] The 10th Blue Bridge Cup Provincial Competition (Software) Real Questions_Programming Questions [C/C++ University Group A]

Fill in the blanks link

Question F: The weight of a complete binary tree (simulate with a queue, pay attention to the data range burst int, remember to debug and output more!)

Insert picture description here
Insert picture description here
Insert picture description here

#include <iostream>
#include <queue>

using namespace std;

int main()
{
    
    
	int n;
	cin >> n;
	
	queue<int> q;
	for(int i = 0;i<n;i++) {
    
    
		int x;
		cin >> x;
		q.push(x);
	}
	int maxv = 0, res_level = 0;
	int m = 1,level = 1;
	while(q.size())
	{
    
    
		long long sum = 0;
		int mt = m;
		while(mt -- && q.size()) // 加多一个判断条件,可能q为空了 
		{
    
    
			int t = q.front();
			q.pop();
			sum += t;
		}
		//cout << "level = " << level <<"  sum = "<<sum << endl;
		if(sum > maxv){
    
    
			maxv = sum;
			res_level = level;
		}
		m *= 2;
		level ++; // 记得更新 
	}
	
	cout << res_level << endl;
	
	/*
	8
	1 6 5 4 3 2 1 100

	*/
	
	return 0;
}


Test Question G: Takeaway priority (simulation, time sorting, the same order merger processing does not require so many special judgments,)

Insert picture description here
Insert picture description here
Insert picture description here
Algorithm 1: The general writing method of y (combine the same orders, great!)

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

#define x first
#define y second

using namespace std;

const int N = 100010;

typedef pair<int,int> PII;

int score[N],last[N],st[N];
PII order[N];

int main()
{
    
    
    int n,m,t;
    scanf("%d%d%d",&n,&m,&t);
    
    for(int i=0;i<m;i++) scanf("%d%d",&order[i].x,&order[i].y);
    
    sort(order,order+m);
    
    for(int i=0;i<m;)
    {
    
    
        int j=i;
        while(j<m && order[j] == order[i]) j++; // 将相同订单合并处理,妙!
        int t=order[i].x, id=order[i].y,cnt=j-i;
        i=j;
        
        score[id] -= t - last[id] -1;
        if(score[id] < 0) score[id] = 0;
        if(score[id] <=3) st[id]=false;
        
        score[id] += cnt * 2;
        if(score[id] > 5) st[id]=true;
        
        last[id]=t;
    }
    
    for(int i=1;i<=n;i++)
    {
    
    
        if(last[i]<t){
    
    
            score[i] -= t - last[i];
            if(score[i] <=3) st[i]=false;
        }
    }
    
    int res=0;
    for(int i=1;i<=n;i++) res+=st[i];
    
    printf("%d\n",res);
    return 0;
}

Algorithm 2: My writing (crazy error correction)

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

typedef pair<int,int> PII;

int n,m,t;
PII order[N];
int last_time[N],priori[N]; // 上一次接单时间,优先级
bool st[N]; // 是否在优先队列中 

int main()
{
    
    
	cin >> n >> m >> t; 
	for(int i =0;i < m ;i ++)
	{
    
    
		int ts,id;
		cin >> ts >> id;
		order[i] = {
    
    ts,id};
	}
	
	sort(order,order+m);
	
	for(int i = 0;i < m ;i ++ )
	{
    
    
		int ts = order[i].first, id = order[i].second;
		
		// 存在相同时刻的订单,特判! 
		if(ts == last_time[id]);
		else priori[id] = max(0,priori[id] - (ts - last_time[id] - 1));
		if(priori[id] <= 3) st[id] = false; // 先减后加
		
		
		priori[id] += 2;
		if(priori[id] > 5) st[id] = true;
		last_time[id] = ts;
		
	}
	
	// 最后还要算一下t时刻的衰减
	for(int i = 1;i <= n;i ++)
	{
    
    
		priori[i] = max(0,priori[i] -(t - last_time[i] ));
		if(priori[i] <= 3) st[i] = false; // 先减后加
	} 
	
	int res = 0;
	for(int i = 1;i <= n;i ++ )
		res += st[i];
	
	cout << res << endl;
	
	//for(int i = 1;i<=n;i++) cout << priori[i]<<" ";
	
	return 0;
		
 } 

Test question H: modify the array (alternative and check set or balanced tree)

Insert picture description hereInsert picture description here
Insert picture description here
Algorithm 1: Alternative union search set (the root element represents the first position that has not been used, time complexity O(N + M))

#include <iostream>

using namespace std;

const int N = 1e6 + 1e5;

int p[N];

int find(int x)
{
    
    
    if(p[x]!=x) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    
    
    int n;
    cin >> n;
    for(int i = 1;i <= N;i ++ ) p[i] = i; // 初始化并查集
    
    for(int i = 1;i <= n;i ++ )
    {
    
    
        int x;
        cin >> x;
        x = find(x);
        cout << x << " ";
        p[x] = x + 1;
    }
    
    return 0;
}

Algorithm 2: Balanced tree (maintenance interval, not written, time complexity O(nlogn))

Test Question I: Candy (state compression DP, data range is small, less than 32 bits)

Insert picture description hereInsert picture description hereInsert picture description here

#include <iostream>
#include <cstring>

using namespace std;

int n,m,k;
int can[100][20], dp[1 << 20];

int main()
{
    
    
    cin >> n >> m >> k;
    for(int i = 0;i < n;i ++ )
        for(int j = 0;j < k ;j ++ )
        {
    
    
            cin >> can[i][j];
            can[i][j] --;  // 下标从0开始
        }

    memset(dp,-1,sizeof dp);
    int lim = 1 << m;
    dp[0] = 0;
    for(int i = 0;i < n;i ++){
    
    
        int t = 0;
        for(int j = 0;j < k ;j ++) t |= (1 << can[i][j]);
        for(int st = 0 ; st < lim; st ++){
    
    
            if(dp[st] == -1) continue;
            int nst = st | t;
            if(dp[nst] == -1 || dp[nst] > dp[st] + 1) dp[nst] = dp[st] + 1;
        }
    }
    cout << dp[lim - 1];
    return 0;
}

Test question J: Combination number problem (Yang Hui triangle to find the combination number + two-dimensional prefix sum)

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

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

using namespace std;

const int N = 2010;

int c[N][N];
int s[N][N];

int main()
{
    
    
    int T, k;
    scanf("%d%d", &T, &k);

    // 杨辉三角求组合数
    for (int i = 0; i < N; i ++ )
        for (int j = 0; j <= i; j ++ )
        {
    
    
            if (!j) c[i][j] = 1 % k;
            else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % k;

            if (!c[i][j]) s[i][j] = 1;
        }
    // 二维前缀和
    for (int i = 0; i < N; i ++ )
        for (int j = 0; j < N; j ++ )
        {
    
    
            if (i) s[i][j] += s[i - 1][j];
            if (j) s[i][j] += s[i][j - 1];
            if (i && j) s[i][j] -= s[i - 1][j - 1];
        }

    while (T -- )
    {
    
    
        int n, m;
        scanf("%d%d", &n, &m);

        printf("%d\n", s[n][m]);
    }

    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43154149/article/details/108904963