CSDN编程题-每日一练(2023-08-15)

CSDN编程题-每日一练(2023-08-15)

  • 一、题目名称:新型美丽数列
  • 二、题目名称:会议安排
  • 三、题目名称:小豚鼠搬家

一、题目名称:新型美丽数列

时间限制:1000ms内存限制:256M

题目描述:

定义美丽数列A: 1. 数列中相邻的数越是靠内相对大小加一,a[2]=a[1]+1,a[n-2]=a[n-1]+1… 2. 距离边缘距离相等的数的大小相等:a[0] = a[n-1],a[1] = a[n-2]… 通过修改最小的数字使得给定数列变成美丽数列。 修改后的值必须仍是正整数。

输入描述:

第一行输入整数n。(1<=n<=1000)表示数列的大小。 第二行输入n个整数。

输出描述:

输出最小修改。

示例:

✔️ 示例1:

输入
3
1 1 1

输出
1

解题思路:

首先,我们需要找到数列中的最小值和最大值,然后找到它们在数列中的下标。接下来,我们需要计算到达边缘的距离,即最小值所在的下标和最大值所在的下标与边缘的距离的较小值。

最后,我们需要计算需要修改的次数,即到达边缘的距离减去最小值。如果计算出来的次数小于等于0,则输出1,否则输出计算出来的次数。这样就得到了最小修改次数,保证仍然为正整数。

代码如下:

n = int(input())
seq = list(map(int, input().split()))

# 找到数列中的最小值和最大值
min_value = min(seq)
max_value = max(seq)

# 找到最大值和最小值的下标
min_index = seq.index(min_value)
max_index = seq.index(max_value)

# 计算到达边缘的距离,min_index表示最小值的下标,max_index表示最大值的下标。n - 1 - max_index表示最大值到达边缘的距离,边缘的下标是n-1。
dis = min(min_index, n - 1 - max_index)

# 计算需要修改的次数,即距离边缘的距离减去最小值
count = dis - min_value

# 输出最小修改次数,保证仍然为正整数
print(max(1, count))

CSDN编程题-每日一练(2023-08-15)_第1张图片

二、题目名称:会议安排

时间限制:1000ms内存限制:256M

题目描述:

开会了!作为一个集体,开会的时候桌子当然是需要和老大相邻的!(老大可能坐在桌子上边) 小艺被分配到排桌椅的活,可是小艺的力气都用在吃上了,怎么可能搬动这些桌椅呢。 她决定用现有的布局当作是会议座位安排。 每个桌子分配一个人。相邻桌子不同的桌子颜色不同。 小艺想知道选择某个桌子之后老大身边能围多少人?

输入描述:

第一行输入2个整数n,m,一个字符c。(1<=n,m<=100)分别表示空间大小和老大指定的桌椅颜色号。 以下n行每行m个字符。’.’代表空地,其他字符表示桌椅。连接在一个且相同的字符表示一个桌子。

输出描述:

输出围着老大的人数。

示例:

✔️示例1

输入
3 4 R
G.B.
BRRA
TTT.

输出
4

解题思路:

在给定桌子布局中,选择某个桌子之后,围绕老大的人数。遍历每个桌子,找出老大指定的颜色号的桌子位置,然后检查这个桌子的上、下、左、右四个方向是否有其他桌子,从而计算围绕老大的人数。

代码如下:

# 读取输入的 n(行数)、m(列数)和 c(老大指定的颜色号)。
n, m, c = map(str, input().split())
n = int(n)
m = int(m)

arr = [] #创建一个列表 table,用于存储老大指定颜色的桌子的位置信息。
for _ in range(n):
    row = input()
    arr.append(row) # 读取桌子布局,并构建一个二维列表arr来表示会议座位布局。

table = []  # 创建一个列表 table,用于存储老大指定颜色的桌子的位置信息。其中,每个位置是一个元组 (row, col),表示桌子所在的行和列。
for i in range(n):  
    for j in range(m):
        if arr[i][j] == c:
            table.append((i, j))  #找到所有与老大相邻的桌子的位置,并将其存储在table列表中。


##创建一个集合 z,用于存储围绕老大的人的颜色号。遍历每个老大桌子的位置:
##遍历上、下、左、右四个方向,计算新的行和列坐标 new_row 和 new_col。
##如果新的坐标在合法范围内,并且对应位置上的字符不是空地('.')且不是老大指定的颜色(c),将该颜色号添加到集合 z 中。
z = set()
for pos in table:
    row, col = pos
    r = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    for dr, dc in r:
        new_row = row + dr
        new_col = col + dc
        if 0 <= new_row < n and 0 <= new_col < m and arr[new_row][new_col] != '.' and arr[new_row][new_col] != c:
            z.add(arr[new_row][new_col])

z_count = len(z) #计算集合 z 的长度,即围绕老大的人数。
print(z_count)

C语言:

#include 
#include 
#include 

typedef struct {
    int row;
    int col;
} Position;

int main() {
    int n, m;
    char c;
    scanf("%d %d %c", &n, &m, &c);

    char arr[n][m + 1];
    for (int i = 0; i < n; ++i) {
        scanf("%s", arr[i]);
    }

    Position table[n * m];
    int table_size = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (arr[i][j] == c) {
                table[table_size].row = i;
                table[table_size].col = j;
                table_size++;
            }
        }
    }

    char z[256] = {0}; 
    for (int i = 0; i < table_size; ++i) {
        Position pos = table[i];
        int row = pos.row;
        int col = pos.col;
        Position r[4] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        for (int j = 0; j < 4; ++j) {
            int new_row = row + r[j].row;
            int new_col = col + r[j].col;
            if (new_row >= 0 && new_row < n && new_col >= 0 && new_col < m
                && arr[new_row][new_col] != '.' && arr[new_row][new_col] != c) {
                z[arr[new_row][new_col]] = 1;
            }
        }
    }

    int z_count = 0;
    for (int i = 0; i < 256; ++i) {
        if (z[i]) {
            z_count++;
        }
    }

    printf("%d\n", z_count);

    return 0;
}

CSDN编程题-每日一练(2023-08-15)_第2张图片

三、题目名称:小豚鼠搬家

时间限制:1000ms内存限制:256M

题目描述:

小艺酱买了一排排格子的小房子n*m,她想让k只小豚鼠每只小豚鼠都有自己的房子。 但是为了不浪费空间,她想要小房子的最外圈尽量每行每列都有一只小豚鼠居住(小豚鼠也可以住在中间的格子,只需保证房子最外围的行和列至少住一只豚鼠即可,无需每行每列都有豚鼠)。 小艺酱想知道自己有多少种方案安排小豚鼠。

输入描述:

输入整数n,m,k。(1<=n,m<=20,0<=k<=n*m)

输出描述:

输出方案数,答案对1e9+7取模。

示例:

✔️示例1
输入
3 3 2

输出
2

解题思路:

通过深度优先搜索(DFS)的方式来解决这个问题。代码的基本思路是尝试将小豚鼠放置在每个格子中,并进行递归搜索。在搜索过程中,记录已经放置的小豚鼠数量、已经被占用的行和列,然后根据题目的条件判断是否满足最外圈至少每行每列都有一只小豚鼠居住的要求。最终,累计满足条件的方案数即可。

代码如下:

n,m,k = map(int,input().split())
def P(n):
    if n < 2:
        return 1
    return n * P(n - 1)
def C(m,n):
    return P(m) // P(m - n) // P(n)
total = 0
 
for i in range(16):
    idx = 0
    row = n
    col = m
    if i & 1: # 对应集合 A,最上边一行无小鼠
        col -= 1
        idx += 1
    if i & 2: # 对应集合 B,最下边一行无小鼠
        col -= 1
        idx += 1
    if i & 4: # 对应集合 C,最左边一列无小鼠
        row -= 1
        idx += 1
    if i & 8: # 对应集合 D,最右边一列无小鼠
        row -= 1
        idx += 1
    #print('i:',i,i&1,i&2,i&4,i&8,'idx:',idx,idx & 1,'row:{},col:{}'.format(row,col))
    if idx & 1:
        total -= int(C(row*col,k))
    else:
        total += int(C(row*col,k))
if k < 2 and m >1 and n >1:
    print(0)
else:
    print(total)

C语言:

#include 

#define MAX_N 30

int a[MAX_N], b[MAX_N];
int ans = 0, cnt = 0;
int n, m, k;

# 定义了一个 dfs 函数,该函数的参数包括当前格子的索引 u,已经放置的小豚鼠数量 c,已占用的行 s 和列 t。
void dfs(int u, int c, int s, int t) {
    if (c == k) { #if (c == k),表示已经放置了 k 只小豚鼠。在这个条件下,通过检查已占用的行和列是否满足题目要求,更新 ans 的值。
        if ((s & 1) && (t & 1)) { 
            if ((s >> (n - 1) & 1) && (t >> (m - 1) & 1)) ans++;
            return;
        }
    }
    if (u >= cnt) return;
    
    // 放小豚鼠
    dfs(u + 1, c + 1, s | (1 << a[u]), t | (1 << b[u]));
    
    // 不放小豚鼠
    dfs(u + 1, c, s, t);
}

int main() {
    scanf("%d %d %d", &n, &m, &k);
    
    # 通过循环生成所有格子的坐标,并调用 dfs 函数进行搜索。
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            a[cnt] = i;
            b[cnt++] = j;
        }
    }
    
    dfs(0, 0, 0, 0); 
    
    printf("%d\n", ans); #输出累计的满足条件的方案数。
    
    return 0;
}

在这里插入图片描述

你可能感兴趣的:(csdn编程题-每日一练,算法,CSDN编程题,每日一练,新型美丽数列,会议安排,小豚鼠搬家)