青岛市2023年入门组市赛

面向信息学竞赛、GESP、蓝桥杯等比赛的教学研究、问题讨论、刷题交流,适合各阶段中小学生,平台入口:csp.magu.ltd。

目录

T1、基站

T2、货车配送

T3、乒乓球


T1、基站

【问题描述】

一个n×m的矩形,单元格(x,y) 表示其位于第x 行第 y列。科学家发明了一种新型网络系统,这种新型网络系统中可以建立多个子网,每个子网需要建立一个1号基站(x1,y1) 和2号基站,该子网可以覆盖以(x1,y1)和(x2,y2) 为顶点的矩形区域(矩形区域的四条边必须平行于行和列)。

1号基站只能在标记为 1的单元格中建立, 2号基站只能在矩形的四个顶点单元格(标记为2 ) 中建立。

不同的子网覆盖区域之间可以相互重叠。

同一个单元格可以建立多个基站。

问最少需要建立多少个子网能将矩形中所有的单元格覆盖。

【输入】

第 1行 1个整数 T,表示有 T组测试数据,每一组数据输入如下:

第 1行 2个整数 n,m,表示矩形的行数和列数。

接下来 n行描述了矩形中单元格的属性。

第 i行包含 m个整数ai,1,ai,2,……,ai,m,用空格分隔。如果 ai,j为 0,表示单元格 (i,j)不能建立任何基站。如果ai,j为1 ,表示单元格 (i,j)可以建立 1号基站。如果 ai,j为 2,表示单元格(i,j) 可以建立 2号基站。

【输出】

输出 T行,每行 1个整数,表示如果能将所有单元格覆盖,需要建立的最少子网数量。

【输入输出样例1】

net.in

net.out

1

4 4

2 0 0 2

0 1 0 0

0 0 1 0

2 0 0 2

4

​​​​​​​【代码】

#include <iostream>
using namespace std;

int a[110][110];

void solve()
{
	int n, m;
	cin >> n >> m;
	bool f = 0;
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= m; j ++) {
			cin >> a[i][j];
			if ((i==1||j==1||i==n||j==m) && a[i][j] == 1) {
				f = 1;
			}
		}
	}
	int ans = f ? 2 : 4;
	cout << ans << endl;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int T;
	cin >> T;
	while (T --)
	{
		solve();
	}
	return 0;
}

T2、货车配送

【问题描述】

某个街区是一个 n × m 的网格。坐标 (i, j) 表示单元格位于第 i 行,第 j 列。每对相邻的单元格之间有一条道路连接,所有的道路都只能按规定的单一方向行驶。道路方向共有三种情况:

由单元格 (i, j) 驶向单元格 (i + 1, j) ,1 ≤ i < n ,方向向下;

由单元格 (i, j) 驶向单元格 (i, j + 1) ,1 ≤ j < m ,i 是奇数,方向向右;

由单元格 (i, j) 驶向单元格 (i, j − 1) ,1 < j ≤ m ,i 是偶数,方向向左。

每个单元格可能是商铺或者住宅,商铺用 0 表示,住宅用 1 表示。一个 7 × 6 的街区示意图如下,空白单元格为商铺。配送公司需要用货车给每个住宅配送生活用品,货车从单元格 (1, 1) 出发,按道路规定方向行驶,从每一个单元格驶向其相邻的单元格均花费 1 分钟。

请问货车最短需要行驶多少分钟才能完成配送任务?(忽略给每个住宅分配生活用品的时间,不考虑货车的回程)。

【输入】

第 1 行包含 2 个整数 n 和 m ,表示行数和列数。接下来 n 行,每行包含 m 个字符,由 0 和 1 组成,0 代表该单元格为商铺,1 代表该单元格为住宅。 保证单元格 (1, 1) 为商铺。

【输出】

输出 1 行 1 个整数,表示货车完成配送任务需要的最短时间(分钟)。

【输入输出样例1】

transport.in

transport.out

7 6

010010

010100

001000

000010

000001

000000

100000

22

【代码】

#include <iostream>
#include <cstring>
using namespace std;

struct Node
{
	int l, r;
}a[210];

char s[210];

int main()
{
	int n, m;
	cin >> n >> m;
	int last = 1;
	for (int i = 1; i <= n; i ++)
	{
		scanf("%s", s+1);
		int l = 1, r = m;
		while (r >= 1 && s[r] != '1') r --;
		while (l <= m && s[l] != '1') l ++;
		a[i] = {l, r};
		if (l != m+1) last = i;
	}
	int ans = last-1, pos = 1;
	for (int i = 1; i <= n; i ++) {
		if (a[i].l == m+1) continue;
		if (i & 1) {
			if (pos > a[i].l) {ans += pos - a[i].l; pos = a[i].l;}
			ans += abs(a[i].r - pos);
			pos = a[i].r;
		}
		else {
			if (pos < a[i].r) {ans += a[i].r - pos; pos = a[i].r;}
			ans += abs(a[i].l - pos);
			pos = a[i].l;
		}
		// printf("ans: %d, pos: %d\n", ans, pos);
	}
	cout << ans << endl;
	return 0;
}

T3、乒乓球

【问题描述】

m个相同的乒乓球分到 n个不同的盒子中,已知第 i个盒子最多能容纳 ai个乒乓球。所有乒乓球要求必须分完,求分配方案数。 答案对 1000000007取模。

【输入】

第一行输入两个正整数 n 和 m。

之后 n 行,每行两个整数 l_i 和 r_i,描述一个区间。

输入共2 行。

第 1行 2个整数,n,m,表示盒子的数量和乒乓球数量。

第 2行 n个整数,a1,a2,……,an ,用空格隔开,表示每个盒子最多可容纳乒乓球的数量。

【输出】

输出 1行 1个整数,表示分配方案数,答案对 1000000007取模。

【输入输出样例 1】

tennis.in

tennis.out

3 5

2 2 3

6

说明: 6种方案分别是: (0,2,3),(1,1,3),(1,2,2),(2,0,3),(2,1,2),(2,2,1)每种方案 按盒子顺序给出数量。

【代码】

#include <iostream>
#include <vector>
using namespace std;

const int MOD = 1000000007;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    vector<int> dp(m + 1, 0);
    dp[0] = 1;  // 0涓箳涔撶悆鏈変竴绉嶆斁娉?

    for (int i = 0; i < n; i++) {
        vector<int> prefix_sum(m + 1, 0);
        prefix_sum[0] = dp[0];
        for (int j = 1; j <= m; j++) {
            prefix_sum[j] = (prefix_sum[j - 1] + dp[j]) % MOD;
        }
        for (int j = 0; j <= m; j++) {
            if (j > a[i]) {
                dp[j] = (prefix_sum[j] - prefix_sum[j - a[i] - 1] + MOD) % MOD;
            } else {
                dp[j] = prefix_sum[j];
            }
        }
    }

    cout << dp[m] << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值