2023 CSP 题目大意还原(2月4号考的)

2023 CSP 题目大意还原(2月4号)

一些没用的话

首先,这次是我第一次正式机试,然后太高兴了就把题目名称全忘了
只记得题目没有意料中的难

T1 (呃…具体名字忘了)

题目大意

打开手机微信,随便找个人点击输入框,即可看见九宫格
这是我随便找的图片
小豫豫要用英文写日记
ta打算用九宫格输入
比如

输入 a a a,就要按 1 1 1下数字2键
输入 c c c,就要按 3 3 3下数字2键
输入 h h h,就要按 2 2 2下数字4键
输入 s s s,就要按 4 4 4下数字7键

怎么样,规律都找到了吧,那就不说了

输入格式

第一行一个整数 n ( n ≤ 100 ) n(n\le100) n(n100)数据范围好像是 100 100 100
接下来 n n n行,每行一个字符串,表示单词 w o r d i word_i wordi

输出格式

一行一个整数表示最少的点击次数

提示

众知所周,输入英文要有空格,所以答案要加上 n − 1 n-1 n1

样例

样例输入1
1
a
样例输出1
1

提示:按1次1键即可

样例输入2
2
sa
a
样例输出2
7

提示:按4次7键和1次1键和1次空格和1次1键即可,共7次

数据范围与约束

怎么办我忘了,但不用担心,范围很小
所有字母均为小写字母,且每行的单词中不存在空格

思路

这题很简单
可以用26个if语句
也可以用数组,map和其他方式存储次数
最后再加上 n − 1 n-1 n1即可

#include <bits/stdc++.h>
using namespace std;
int read(){
	int x;
	scanf("%d",&x);
	return x;
}
int n,ans;
string s;
map<char,int>m;
int main(){
	m['a']=1,m['d']=1,m['g']=1,m['j']=1,m['m']=1,m['p']=1,m['t']=1,m['w']=1,
	m['b']=2,m['e']=2,m['h']=2,m['k']=2,m['n']=2,m['q']=2,m['u']=2,m['x']=2,
	m['c']=3,m['f']=3,m['i']=3,m['l']=3,m['o']=3,m['r']=3,m['v']=3,m['y']=3,
	m['s']=4,m['z']=4;
	n=read();
	for(int i=1;i<=n;i++){
		cin>>s;
		for(int j=0;j<s.size();j++) ans+=m[s[j]];
		ans++;
	}
	printf("%d",ans-1);
	return 0;
}

T2 (呃…具体名字忘了)

题目大意

给定一个整数 n n n和一个整数 k k k
输入 n n n个整数 a i a_i ai表示每种药材的数量
再输入 n n n个整数 v i s i vis_i visi表示是否处理过第 i i i个药材
0表示未处理,1表示已经处理

然后让你找一个长度为 k k k的区间
使 a i , a i + 1 , . . . . . . , a k a_i,a_{i+1},......,a_k ai,ai+1,......,ak都处理一下
即使 v i s i , v i s i + 1 , . . . . . . , v i s k vis_i,vis_{i+1},......,vis_k visi,visi+1,......,visk都变为1

最后求出所有已经处理过的药材的最大数量
(只要是 v i s i = 1 vis_i=1 visi=1的,都累加上)

输入格式

一行2个整数 n n n k k k 表示 n n n种药材和选取区间长度 k k k
接下来 n n n个整数 a i a_i ai表示每种药材的数量
接下来 n n n个整数 v i s i vis_i visi表示每种药材是否处理过

输出格式

一行一个整数表示答案

样例

样例输入1
3 1
10 5 3
0 0 1
样例输出1
13

选取[1,1]

样例输入2
5 3
10 6 8 1 9
0 0 0 0 1
样例输出2
33

选取[1,3]

数据范围与约束

对于 30 % 30\% 30%的数据,满足 1 ≤ k < n ≤ 1000 1 \le k < n \le1000 1k<n1000
对于 20 % 20\% 20%的数据,满足 n = k n=k n=k
对于 100 % 100\% 100%的数据,满足 1 ≤ k < n ≤ 1 0 5 , 1 ≤ a i ≤ 1 0 5 1\le k < n \le 10^5,1 \le a_i \le 10^5 1k<n105,1ai105
好像是这样的吧…

思路

30 % 30\% 30%
前缀和优化,暴力枚举每个区间,累加即可
时间复杂度: O ( n 2 ) O(n^2) O(n2)

20 % 20\% 20%
《骗分》
特判+累加和即可
时间复杂度: O ( n ) O(n) O(n)

100 % 100\% 100%
我的思路:如果 v i s i = 1 vis_i=1 visi=1,那么就让 s u m + = a i , a i = 0 sum+=a_i,a_i=0 sum+=ai,ai=0
之后求出前缀和,双指针求最大值 m a x x maxx maxx
输出 s u m + m a x x sum+maxx sum+maxx即可

我不知道对不对,应该对吧
时间复杂度: O ( n ) O(n) O(n)

#include <bits/stdc++.h>
using namespace std;
int read(){
	int x;
	scanf("%d",&x);
	return x;
}
const int N=100010;
long long n,k,a[N],p[N];
int vis[N];
long long s,maxx;
int main(){
	n=read(),k=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++){
		vis[i]=read();
		if(vis[i]==1) s+=a[i],a[i]=0;
	}
	for(int i=1;i<=n;i++) p[i]=p[i-1]+a[i];
	int l=1,r=k;
	for(int i=1;i<=n-k+1;i++){
		maxx=max(maxx,p[r]-p[l-1]);
		l++,r++;
	}
	printf("%lld",maxx+s);
	return 0;
}
/*
5 3
10 6 8 1 9
0 0 0 0 1
*/

T3 (呃…具体名字忘了)

题目大意

让一个小球在 n × m n \times m n×m的方阵中进行滚动
方阵 a i j a_{ij} aij有一个大写字母是U,D,L,R,O中的一个
对应了上下左右四个方向

当小球到达 ( x , y ) (x,y) (x,y)
if(a[x][y]==‘U’) x- -;
if(a[x][y]==‘D’) x++;
if(a[x][y]==‘L’) y- -;
if(a[x][y]==‘R’) y++;

懂得都懂,小球到点 O O O时就到了终点,当然不能超出边界

问:在方阵中每个格子都放小球共有几个小球能到终点

输入格式

第一行 n , m n,m n,m
接下来 n n n行每行 m m m个字符

输出格式

a n s ans ans表示能到终点的小球数量

样例

样例输入1
4 4
RRRD
RDRU
RDRU
RRRO
样例输出1
8

样例输入2
1 1
O
样例输出2
1

数据范围与约束

对于 30 % 30\% 30%的数据,满足 1 ≤ n < m ≤ 100 1 \le n < m \le100 1n<m100
对于 100 % 100\% 100%的数据,满足 1 ≤ n < m ≤ 2000 1\le n < m \le 2000 1n<m2000
好像是这样的吧…

思路

30 % 30\% 30%
枚举每个点,做dfs
就这么简单
时间复杂度: O ( n 2 m 2 ) O(n^2m^2) O(n2m2)
100 % 100\% 100%
但还有更简单的,用逆向思维,从终点 O O O出发查找相邻的哪些点能通入终点,之后再dfs那个点即可
时间复杂度: O ( n m ) O(nm) O(nm)

#include <bits/stdc++.h>
using namespace std;
char a[1010][1010];
bool vis[1010][1010];
int ans,n,m,xx,yy;
int read(){
	int x;
	scanf("%d",&x);
	return x;
}
void dfs(int x,int y){
	if(vis[x][y]) return;
	vis[x][y]=1;//可以不考虑边界
	ans++;
	if(a[x][y-1]=='R') dfs(x,y-1);
	if(a[x][y+1]=='L') dfs(x,y+1);
	if(a[x-1][y]=='D') dfs(x-1,y);
	if(a[x+1][y]=='U') dfs(x+1,y);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			if(a[i][j]=='O') xx=i,yy=j;
		}	
	dfs(xx,yy);
	printf("%d",ans);
	return 0;
}
/*
4 4
RRRD
RDRU
RDRU
RRRO
*/

T4 (呃…具体名字忘了)

T4由于题目长度过长,且难度过大,导致作者没心情写
所以一会在写…
放心,我保证说到做到
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值