P14358 [CSP-J 2025] 座位 / seat

P14358 [CSP-J 2025] 座位 / seat(官方数据)

题目描述

CSP-J 2025 第二轮正在进行。小 R 所在的考场共有 n × m n \times m n×m 名考生,其中所有考生的 CSP-J 2025 第一轮成绩互不相同。所有 n × m n \times m n×m 名考生将按照 CSP-J 2025 第一轮的成绩,由高到低蛇形分配座位,排列成 n n n 行 m m m 列。具体地,设小 R 所在的考场的所有考生的成绩从高到低分别为 s 1 > s 2 > ⋯ > s n × m s_1 > s_2 > \dots > s_{n \times m} s1​>s2​>⋯>sn×m​,则成绩为 s 1 s_1 s1​ 的考生的座位为第 1 列第 1 1 1 行,成绩为 s 2 s_2 s2​ 的考生的座位为第 1 1 1 列第 2 2 2 行, … \dots …,成绩为 s n s_n sn​ 的考生的座位为第 1 1 1 列第 n n n 行,成绩为 s n + 1 s_{n+1} sn+1​ 的考生的座位为第 2 2 2 列第 n n n 行, … \dots …,成绩为 s 2 n s_{2n} s2n​ 的考生的座位为第 2 2 2 列第 1 1 1 行,成绩为 s 2 n + 1 s_{2n+1} s2n+1​ 的考生的座位为第 3 3 3 列第 1 1 1 行,以此类推。

例如,若 n = 4 , m = 5 n = 4, m = 5 n=4,m=5,则所有 4 × 5 = 20 4 \times 5 = 20 4×5=20 名考生将按照 CSP-J 2025 第一轮成绩从高到低的顺序,根据下图中的箭头顺序分配座位。

:::align{center}

:::

给定小 R 所在的考场座位的行数 n n n 与列数 m m m,以及小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩 a 1 , a 2 , … , a n × m a_1, a_2, \dots, a_{n \times m} a1​,a2​,…,an×m​,其中 a 1 a_1 a1​ 为小 R CSP-J 2025 第一轮的成绩,你需要帮助小 R 求出,他的座位为第几列第几行。

输入格式

输入的第一行包含两个正整数 n , m n, m n,m,分别表示小 R 所在的考场座位的行数与列数。

输入的第二行包含 n × m n \times m n×m 个正整数 a 1 , a 2 , … , a n × m a_1, a_2, \dots, a_{n \times m} a1​,a2​,…,an×m​,分别表示小 R 所在的考场的所有考生 CSP-J 2025 第一轮的成绩,其中 a 1 a_1 a1​ 为小 R CSP-J 2025 第一轮的成绩。

输出格式

输出一行两个正整数 c , r c, r c,r,表示小 R 的座位为第 c c c 列第 r r r 行。

输入输出样例 #1

输入 #1

2 2
99 100 97 98

输出 #1

1 2

输入输出样例 #2

输入 #2

2 2
98 99 100 97

输出 #2

2 2

输入输出样例 #3

输入 #3

3 3
94 95 96 97 98 99 100 93 92

输出 #3

3 1

说明/提示

【样例 1 解释】

按照成绩从高到低的顺序,成绩为 100 100 100 的考生的座位为第 1 1 1 列第 1 1 1 行,成绩为 99 99 99 的考生的座位为第 1 1 1 列第 2 2 2 行,成绩为 98 98 98 的考生的座位为第 2 2 2 列第 2 2 2 行,成绩为 97 97 97 的考生的座位为第 2 2 2 列第 1 1 1 行。小 R 的成绩为 99 99 99,因此座位为第 1 1 1 列第 2 2 2 行。

【样例 2 解释】

按照成绩从高到低的顺序,成绩为 100 100 100 的考生的座位为第 1 1 1 列第 1 1 1 行,成绩为 99 99 99 的考生的座位为第 1 1 1 列第 2 2 2 行,成绩为 98 98 98 的考生的座位为第 2 2 2 列第 2 2 2 行,成绩为 97 97 97 的考生的座位为第 2 2 2 列第 1 1 1 行。小 R 的成绩为 98 98 98,因此座位为第 2 2 2 列第 2 2 2 行。

【数据范围】

对于所有测试数据,保证:

  • 1 ≤ n ≤ 10 1 \leq n \leq 10 1≤n≤10, 1 ≤ m ≤ 10 1 \leq m \leq 10 1≤m≤10;
  • 对于所有 1 ≤ i ≤ n × m 1 \leq i \leq n \times m 1≤i≤n×m,均有 1 ≤ a i ≤ 100 1 \leq a_i \leq 100 1≤ai​≤100,且 a 1 , a 2 , … , a n × m a_1, a_2, \dots, a_{n \times m} a1​,a2​,…,an×m​ 互不相同。

::cute-table{tuack}

测试点编号 n ≤ n \leq n≤ m ≤ m \leq m≤特殊性质
1 1 1 1 1 1 1 1 1AB
2 , 3 2, 3 2,3^ 10 10 10无
4 , 5 4, 5 4,5 10 10 10 1 1 1^
6 6 6 2 2 2 2 2 2A
7 7 7^^B
8 , 9 8, 9 8,9^^无
10 10 10^ 10 10 10A
11 11 11^^B
12 ∼ 14 12 \sim 14 12∼14^^无
15 ∼ 17 15 \sim 17 15∼17 10 10 10 2 2 2^
18 ∼ 20 18 \sim 20 18∼20^ 10 10 10^

特殊性质 A:对于所有 1 ≤ i ≤ n × m 1 \leq i \leq n \times m 1≤i≤n×m,均有 a i = i a_i = i ai​=i。

特殊性质 B:对于所有 1 ≤ i ≤ n × m 1 \leq i \leq n \times m 1≤i≤n×m,均有 a i = n × m − i + 1 a_i = n \times m - i + 1 ai​=n×m−i+1。

题意:对于nm个正整数(各不相同),按照从大到小的顺序,依次如图蛇形填入nm的矩阵,输出n*m个正整数中的第一个数在矩阵中的位置。

题解:

方案1,首先确定第一个数 在n*m个数从小到大排序之后的 位次idx。然后通过计算算出位次idx 在矩阵中的行列。

蛇形填充按照从上往下填充第一列,再从下往上填充第二列,依次类推,直到填充完毕,一列n个数,因此 通过 idx/n 可计算得到 总共有多少列,如果可以整除,则为整列,否则列数为idx/n+1;即列:int c=idx%n==0?idx/n:idx/n+1;

而 idx%n 的结果即为最后一列剩余的数字,即行数,此外,如果余数为0,则意味着是整列,行数为n。即行:int r=idx%n==0?n:idx%n; 此时行数指的是从上往下的行数。需要注意的是:奇数列从上往下,偶数列从下往上,因此如果是偶数列,其行数应该为n+1-r。

#include<bits/stdc++.h>
using namespace std;
int n, m, arr[105];
bool cmp(int a, int b){
	return a>b; 
}
int main(){
	cin>>n>>m; 
	for(int i=1; i<=n*m; i++) cin>>arr[i];
	int num=arr[1]; //num存储第一个数  
	sort(arr+1, arr+n*m+1, cmp); //排序
	int idx; //求第一个数排序在排序后的位次
	for(int i=1; i<=n*m; i++){ 
		if(arr[i]==num){
			idx=i;
			break;
		}
	}
	//计算 列、行
	int c=idx%n==0?idx/n:idx/n+1; //列 
	int r=idx%n==0?n:idx%n; //行 
	//考虑奇数列的不同情况
	if(c%2==1) cout<<c<<" "<<r<<endl;
	else cout<<c<<" "<<n+1-r<<endl;
	return 0;
}

方案2,将n*m个数从大到小进行排序,然后按照题目要求依次将这些数蛇形填充进二维矩阵中,当填充到原本的第一个数时,当前的填充位置也即所求。

#include<bits/stdc++.h>
using namespace std;
int n, m, arr[105], mat[15][15];
bool cmp(int a, int b) {
	return a>b;
}
int main() {
	cin>>n>>m;
	for(int i=1; i<=n*m; i++) cin>>arr[i];
	int num=arr[1]; //num存储第一个数  
	sort(arr+1, arr+n*m+1, cmp); //排序
	int idx=1; //从第一个数开始依次蛇形填充进二维矩阵中
	for(int c=1; c<=m; c++) { //按列填充
		if(c%2==1) { //奇数列
			for(int r=1; r<=n; r++) { //从上往下填充
				if(arr[idx]==num) { //填充到原本的第一个数
					cout<<c<<" "<<r<<endl;
					return 0;
				}
				mat[r][c]=arr[idx++];
			}
		} else { //偶数列
			for(int r=n; r>=1; r--) { //从下往上填充
				if(arr[idx]==num) { //填充到原本的第一个数
					cout<<c<<" "<<r<<endl;
					return 0;
				}
				mat[r][c]=arr[idx++];
			}
		}
	}
	return 0;
}
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐