跳到主要内容

CSP-j 2025总结

alt text

P14357 [CSP-J 2025] 拼数 / number(官方数据)​

题目描述​

小 R 正在学习字符串处理。小 X 给了小 R 一个字符串 ss,其中 ss 仅包含小写英文字母及数字,且包含至少一个 1∼91 \sim 9 中的数字。小 X 希望小 R 使用 ss 中的任意多个数字,按任意顺序拼成一个正整数。注意:小 R 可以选择 ss 中相同的数字,但每个数字只能使用一次。例如,若 ss 为 1a01b\tt 1a01b,则小 R 可以同时选择第 1,3,41,3,4 个字符,分别为 1,0,11,0,1,拼成正整数 101101 或 110110;但小 R 不能拼成正整数 111111,因为 ss 仅包含两个数字 11。小 R 想知道,在他所有能拼成的正整数中,最大的是多少。你需要帮助小 R 求出他能拼成的正整数的最大值。

输入格式​

输入的第一行包含一个字符串 ss,表示小 X 给小 R 的字符串。

输出格式​

输出一行一个正整数,表示小 R 能拼成的正整数的最大值。

输入输出样例 #1​

输入 #1​

5

输出 #1​

5

输入输出样例 #2​

输入 #2​

290es1q0

输出 #2​

92100

说明/提示​

【样例 2 解释】​

ss 包含数字 2,9,0,1,02,9,0,1,0。可以证明,小 R 拼成的正整数的最大值为 9210092100。

【样例 3】​

见选手目录下的 number/number3.innumber/number3.in 与 number/number3.ansnumber/number3.ans。该样例满足测试点 9∼119 \sim 11 的约束条件。

【样例 4】​

见选手目录下的 number/number4.innumber/number4.in 与 number/number4.ansnumber/number4.ans。该样例满足测试点 2020 的约束条件。

【数据范围】​

设 ∣s∣|s| 为字符串 ss 的长度。对于所有测试数据,保证:

  • 1≤∣s∣≤1061 \leq |s| \leq 10^6;
  • ss 仅包含小写英文字母及数字,且包含至少一个 1∼91 \sim 9 中的数字。
测试点编号∣s∣≤\lvert s\rvert \leq特殊性质
1111A
2222^
33^无
441010A
5,65,6^无
7,87,810210^2A
9∼119 \sim 11^无
121210310^3A
13,1413,14^无
151510510^5A
16,1716,17^B
18,1918,19^无
202010610^6A
21,2221,22^B
23∼2523 \sim 25^无
  • 特殊性质 A:ss 仅包含数字。
  • 特殊性质 B:ss 仅包含不超过 10310^3 个数字。

优秀代码:​

曾宪焘/张顾维/何钰川/杨晋延/喻品序
#include<bits/stdc++.h>
using namespace std;

string s;
int a[10];

int main() {
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
cin >> s;
memset(a,0,sizeof(a));
for(int i=0; i<s.size(); ++i) {
if(s[i]>='0' && s[i]<='9') {
int number=s[i]-'0';
++a[number];
}
}
for(int i=9;i>=0;i--){
if(a[i]!=0){
for(int j=1;j<=a[i];++j){
cout << i;
}
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
周子沐,胡歆煜,苏昊然
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
string s;
int mx,n,a[N],x;
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
cin >> s;
n=s.length();
for (int i=0;i<n;i++)
{
if ('0'<=s[i]&&s[i]<='9')
{
x+=1;
a[x]=(int)s[i]-48;
}
}
sort(a+1,a+x+1);
for (int i=x;i>=1;i--)
{
printf("%d",a[i]);
}
fclose(stdin);
fclose(stdout);
return 0;
}
#include<bits/stdc++.h>
using namespace std;

int a[10];

int main() {
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
cin >> s;

char c ;
while(c=getchar(), c!=EOF) {
if(c >='0' && c <='9') {
int number=c-'0';
a[number]++;
}
}
for(int i=9;i>=0;i--){
if(a[i]!=0){
for(int j=1;j<=a[i];++j){
cout << i;
}
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
万分可惜:黄浩宇
#include<bits/stdc++.h> 
using namespace std;
int a[100005]; //WRONG: 数组定义小了!
int ping(int cnt){
int maxx=0;
sort(a,a+cnt);
for(int i=cnt-1;i>=0;i--)
cout<<a[i];
//WRONG: 没有返回值!
}
int main(){
//freopen("number.in","r",stdin);
//freopen("number.out","w",stdout);
string s;
cin>>s;
int l=s.size();
int cnt=0;
for(int i=0;i<l;i++){
if(s[i]>='0'&&s[i]<='9'){
a[cnt]=s[i]-'0';
cnt++;
}
}
ping(cnt);
return 0;
}

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

题目描述​

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

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

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

输入格式​

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

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

输出格式​

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

输入输出样例 #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 解释】​

按照成绩从高到低的顺序,成绩为 100100 的考生的座位为第 11 列第 11 行,成绩为 9999 的考生的座位为第 11 列第 22 行,成绩为 9898 的考生的座位为第 22 列第 22 行,成绩为 9797 的考生的座位为第 22 列第 11 行。小 R 的成绩为 9999,因此座位为第 11 列第 22 行。

【样例 2 解释】​

按照成绩从高到低的顺序,成绩为 100100 的考生的座位为第 11 列第 11 行,成绩为 9999 的考生的座位为第 11 列第 22 行,成绩为 9898 的考生的座位为第 22 列第 22 行,成绩为 9797 的考生的座位为第 22 列第 11 行。小 R 的成绩为 9898,因此座位为第 22 列第 22 行。

【数据范围】​

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

  • 1≤n≤101 \leq n \leq 10, 1≤m≤101 \leq m \leq 10;
  • 对于所有 1≤i≤n×m1 \leq i \leq n \times m,均有 1≤ai≤1001 \leq a_i \leq 100,且 a1,a2,…,an×ma_1, a_2, \dots, a_{n \times m} 互不相同。
测试点编号n≤n \leqm≤m \leq特殊性质
111111AB
2,32, 3^1010无
4,54, 5101011^
662222A
77^^B
8,98, 9^^无
1010^1010A
1111^^B
12∼1412 \sim 14^^无
15∼1715 \sim 17101022^
18∼2018 \sim 20^1010^

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

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

优秀代码:​

何钰川
#include<bits/stdc++.h>
using namespace std;
int a[105];
int main(){
freopen("seat.in","r",stdin);
freopen("seat.out","w",stdout);
int n,m,q=1,x,y;
cin>>n>>m;
cin>>a[1];
for(int i=2;i<=n*m;i++){ //简单高效得到名次
cin>>a[i];
if(a[i]>a[1])
q++;
}
x=q%n;
y=q/n;
if(x==0){
if(y%2==0)
cout<<y<<" "<<1;
else
cout<<y<<" "<<n;
}
else{
y++;
if(y%2==0)
cout<<y<<" "<<n-x+1;
else
cout<<y<<" "<<x;
}
fclose(stdin);
fclose(stdout);
return 0;
}
胡歆煜/黄浩宇
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+5;
int a[N];
bool cmp(int x,int y){
return x>y;
}
int main(){
freopen("seat.in","r",stdin);
freopen("seat.out","w",stdout);
int n,m;
cin>>n>>m;
for(int i=0;i<n*m;i++)
cin>>a[i];
int f=a[0];
sort(a+0,a+n*m,cmp);
for(int i=0;i<n*m;i++){
if(f==a[i]){
f=i;
break;
}
}
//由于从0计数,刚好简化了计算,但要注意列奇偶判断就要用反的
int r=f/n+1,c;
if((f/n)&1==1)
c=n-(f%n);
else
c=1+(f%n);
cout<<r<<" "<<c;
return 0;
}
苏
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[105],mm[15][15];
int main(){
freopen("seat.in","r",stdin);
freopen("seat.out","w",stdout);
scanf("%d%d",&n,&m);
int l=n*m,R,num=0; //WRONG: num=1
for(int i=1;i<=l;i++){
scanf("%d",&a[i]);
if(i==1) R=a[i];
}
sort(a+1,a+l); //WRONG: 应该是sort(a+1,a+1+l);
for(int i=l;i>=1;i--){
if(R==a[i]) break;
num++; //WRONG: 或者num++ 放到上面一行

//GOOD: 模拟法,但做了优化
int idx=0;
for(int i=1;i<=m;i++){
if(i%2==1){
for(int j=1;j<=n;j++){
idx++;
if(num==idx){
printf("%d %d",i,j);
return 0;
}

}
}
else{
for(int j=n;j>=1;j--){
idx++;
if(num==idx){
printf("%d %d",i,j);
return 0;
}

}
}
}
return 0;
}

*学习笔记​

暂没有学习笔记,快来抢first blood !