第36次ccf-csp题解(思维)

  • 比赛感受

这会刚打完上海icpc,比起区域赛的题,这个简单太多了。
感受还不错,写的很顺手。除了第3题,其他3题都是一发过。
刷题得长期刷。





 
 

  • A题 移动

题意:f : y+1 ;  b : y-1 ;   l : x-1 ;  r : x+1

 
一个简单的模拟,若当前操作使机器人移出场地,那么使机器人移回来就好


   
   
#include <bits/stdc++.h>
#define int long long
using namespace std;
void ooo(int x){
cout<<x<<'\n';
}
signed main()
{
int n, k;cin>>n>>k;
for(int i=1;i<=k;i++){
int x, y;cin>>x>>y;
string s;cin>>s;
int len=s.size();
for(int j=0;j<len;j++){
if(s[j]=='f')y+=1;
else if(s[j]=='b')y-=1;
else if(s[j]=='l')x-=1;
else x+=1;
if(y>n)y--;
if(y<1)y++;
if(x>n)x--;
if(x<1)x++;
}
cout<<x<<' '<<y<<'\n';
}
return 0;
}

  • B题 梦境巡查

这个题不算太难,有点思维,对码力要求不高。

  

它假设当bi为0时求初始时要带的最小补给。

关键在于怎样维护bi=0时,全程中所拥有补给的最小量(为负数表示还需要多少补给) 所以就是一个单点修改,以bi为分界处,维护前半段和后半段最小值,对两段最小值取最小值,为负数则取绝对值,为非负数则为0。

   


   
   
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int xmmm=2e5+10;
int a[xmmm], b[xmmm];
int c[xmmm];
int sum[xmmm];
int pmi[xmmm], lmi[xmmm];
int ans[xmmm];
void ooo(int x){
cout<<x<<'\n';
}
signed main()
{
int n;cin>>n;
for(int i=0;i<=n;i++){
cin>>a[i];
c[i*2+1]=0-a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
c[i*2]=b[i];
}
pmi[0]=lmi[2*n+2]=0-1e10;
for(int i=1;i<=2*n+1;i++){
sum[i]=sum[i-1]+c[i];
}
for(int i=1;i<=2*n+1;i++){
if(i==1)pmi[i]=sum[i];
else pmi[i]=min(pmi[i-1], sum[i]);
}
for(int i=2*n+1;i>=1;i--){
if(i==2*n+1)lmi[i]=sum[i];
else lmi[i]=min(lmi[i+1], sum[i]);
}
for(int i=1;i<=n;i++){
int pos=i*2;
int t1=pmi[pos-1];
int t2=lmi[pos]-b[i];
ans[i]=min(t1, t2);
}
for(int i=1;i<=n;i++){
if(ans[i]<0)cout<<0-ans[i]<<' ';
else cout<<0<<' ';
}
return 0;
}
/*
3
5 5 5 5
0 100 0
3
9 4 6 2
9 4 6
*/

  • D题 跳房子

这个题感觉还没有C题难。
这其实是一个很简单的图遍历的问题
建完边还是只有一个前驱的这种,简单版的迪杰斯特拉。
处理出b数组,每个点只入队列一次。


   
   
#include <bits/stdc++.h>
//#define int long long
using namespace std;
void ooo(int x){
cout<<x<<'\n';
}
struct p{
int id, num;
};
const int xmmm=2e5+10;
int a[xmmm], b[xmmm], k[xmmm];
int dis[xmmm];
bool vis[xmmm];
signed main()
{
int n;cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=i-a[i];
}
for(int i=1;i<=n;i++)cin>>k[i];
int pos=0;
queue<p>q;
//q.clear();
q.push(p{1, 0});
int ans=-1;
while(!q.empty()){
p t=q.front();q.pop();
if(vis[t.id])continue;
vis[t.id]=1;
if(t.id==n){
ans=t.num;break;
}
int x=t.id;
if(x+k[x]<=pos)continue;
if(x+k[x]>=n){
q.push(p{n, t.num+1});
continue;
}
for(int i=max(pos+1, x+1);i<=min(n, x+k[x]);i++){
q.push(p{b[i], t.num+1});
}
pos=max(pos, x+k[x]);
}
cout<<ans<<'\n';
return 0;
}
/*
5
0 1 2 3 0
3 4 4 10 15
10
0 1 1 1 1 3 1 0 3 0
2 4 5 4 1 4 1 3 5 3
*/

  • C题 缓存模拟


一个大模拟按他的要求来就好了,详细的可以看注释


   
   
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int xxx=3e5;
const int xx=7e4;
int head[xxx],nnum[xxx];
// m组里有多少个
struct p{
int x, y;
};
vector<p>ans;
void ooo(int x){
cout<<x<<'\n';
};
struct node {
int id, num;
bool operator<(const node &a)const {return a.num<num;}
};
priority_queue<node>qq[xx];
unordered_map<int, int>a, vis; // 位置//是否修改
signed main()
{
int n, m, q;cin>>n>>m>>q;
for(int i=1;i<=q;i++){
int x, y;cin>>x>>y;
if(a[y]){ / /判断是否命中
int pos=(y / n ) %m;
head[pos]++;
qq[pos].push(node{y, head[pos]});
a[y]=head[pos];
if(x==0)x=x;
else {
vis[y]=1; //判断是否改写
}
}
else {
int pos=( y / n )%m; //位置
if(nnum[pos]==n){ //如果已经满了
while(!qq[pos].empty()){
node tt=qq[pos].top();qq[pos].pop();
if(a[tt.id]!=tt.num)continue;
if(vis[tt.id]){
//cout<<"pos"<<tt.id<<' '<<tt.num<<' '<<a[tt.id]<<'\n';
ans.push_back(p{(int)1, tt.id});
vis[tt.id]=0;
}
head[pos]++;
a[y]=head[pos];
if(x)vis[y]=1;
qq[pos].push(node{y, head[pos]});
ans.push_back(p{(int)0, y});
a[tt.id]=0;break;
}
}
else {
head[pos]++;
a[y]=head[pos];
nnum[pos]++;
qq[pos].push(node{y, head[pos]});
if(x)vis[y]=1;
ans.push_back(p{(int)0, y});
}
}
}
int len=ans.size();
for(int i=0;i<len;i++){
cout<<ans[i].x<<' '<<ans[i].y<<'\n';
}
return 0;
}
/*
4 8 8
0 0
0 1
1 2
0 1
1 0
0 32
1 33
0 34
1 1 3
1 0
1 1
0 2
*/

  • 自我总结

这次写题的顺序是1243,再写一点点。

原创作者: 1747176348mi 转载于: https://www.cnblogs.com/1747176348mi/p/18623758
### 关于CSP36认证的信息 中国计算机学会(CCF)举办的CSP(Computer Software Professional Certification,软件能力专业认证),旨在评估个人在编程和算法设计方面的能力。根据已有的资料以及相关背景信息[^1],可以推测CSP认证的内容通常围绕以下几个核心领域展开: #### 1. **CSP认证概述** CSP认证是一种面向程序员的职业技能评测工具,主要考察考生的程序设计能力和实际解决问题的能力。每认证都会设置若干道题目,涉及数据结构、算法设计、复杂度分析等内容。对于第36认证的具体细节,虽然未提供直接引用材料,但可以根据以往的经验推断其形式与内容。 - 考试时间一般为每年固定日期举行,具体安排需参考官方公告。 - 题目难度分为基础题和综合应用题两类,覆盖范围广泛,可能包括但不限于字符串处理、图论、动态规划等领域[^2]。 #### 2. **IT安全相关内容** 关于IT安全方面的考核,在某些特定场可能会有所体现。例如权限管理、加密解密技术的应用场景等都可能是潜在考点之一。从之前的一道典型例题来看,“权限查询”这一类问题曾被纳入考试范畴内[^4]。此类问题往往要求参赛者具备扎实的基础理论知识同时还需要一定的实战经验来应对复杂的业务逻辑需求。 以下是基于Java语言实现的一个简单版本“权限查询”的解决方案作为示范: ```java import java.util.*; public class PermissionCheck { public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); // 用户数量 List<Integer> permissions=new ArrayList<>(); for(int i=0;i<n;i++)permissions.add(sc.nextInt()); String s=sc.next(); boolean result=true; for(char ch:s.toCharArray()){ if(ch=='A'&&permissions.get(0)==0){result=false;break;} else if(ch=='B'&&permissions.get(1)==0){result=false;break;} else if(ch=='C'&&permissions.get(2)==0){result=false;break;} } System.out.println(result?"true":"false"); } } ``` 此代码片段展示了如何通过读取输入数据并判断给定条件下是否满足访问条件的过程。需要注意的是这只是一个简化版的例子,并不代表真实环境中所有情况都能如此轻易解决[^3]。 #### 3. **认证机制解析** 针对会员权益部分提到过每位新注册成为正式会员的人都享有唯一一免报名费用参与测试的权利;即使后续继续缴纳年费维持身份状态亦或是重新获取资格也无法再享受此项优惠待遇。因此建议有意报考人员尽早行动以免错过最佳时机。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值