首页 > 其他分享 >CSP-J 济南刷题训练营

CSP-J 济南刷题训练营

时间:2023-07-24 21:26:27浏览次数:47  
标签:格子 int 训练营 路径 合并 交集 枚举 CSP 刷题

Day 1:基础算法

枚举

从可能得集合中一一尝试统计贡献。

模拟

模拟题目中要求的操作

NOIP2014 生活大爆炸版石头剪刀布

洛谷链接:P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布

注意到赢了是得 \(1\) 分,平局和输都是 \(0\) 分,所以我们直接根据题意打表。

int Vs[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};

然后我们又发现是循环出拳,所以我们用取模的方法来实现。

完整代码:

#include <bits/stdc++.h>
using namespace std;
int n,lena,lenb;//题面所示 
int a[205],b[205];//两个人的出拳顺序
int pointa,pointb;//两个人的得分情况 
int Vs[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};//打表 
signed main(){
    cin>>n>>lena>>lenb;
    for(int i=0;i<lena;i++)cin>>a[i];
    for(int i=0;i<lenb;i++)cin>>b[i];
    for(int i=0;i<n;i++){
        pointa+=Vs[a[i%lena]][b[i%lenb]];
        pointb+=Vs[b[i%lenb]][a[i%lena]];//取模 
    }
    cout<<pointa<<' '<<pointb<<endl;
    return 0;
}

CODECHEF PAINTING

  • 题面:
    一个无穷大的网格,机器人初始在 \(a_{0,0}\) 上。进行 \(n\) 次操作,每次操作给定一个字符 \(s\) 和一个代表距离的正整数 \(d\)。字符共有四种可能,U 代表向上,D 代表向下,R 表示向左,L 代表向右。机器人会向相应的方向行进 \(d\) 个单位长度,并将其经过的位置染为白色。问每次移动后新增加的白色格子的数量。

  • 注意点:

  1. 一个格子可能被重复染色,但是我们只能计算一次(第一次)。
  2. 但是不能挨个枚举走过的每个格子,会 TLE。
  • 因此得到一个大致的思路:
  1. 依次计算每次路径走过的格子的数量。
  2. 枚举之前的路径计算交集。
  3. 对交集进行处理,求已经被染色的格子的数量。
  4. 用总共经过的格子的数量减去交集的格子的数量就是我们每次要求的答案。
  • 计算交集
  1. 如果是计算横的路径和竖的路径的交集,只可能是有一个格子或者是空集。
  2. 如果同竖或同横的话,两条路径同行(列)交集为空或者是该行(列)的一个区间,不同行(列)交集就为空。
  • 整合
    我们通过上述分讨发现两条路径之间的交集不是为空就是该路径上的一个区间(一个点也算区间),对这些交集求并后可以在排序后将重复的部分合并起来。

小结

  • 用到模拟和枚举的题细节复杂且多,需要注意读题和模拟样例。

  • 先写代码框架后对其拆分成更细的模块,进行补充。

递推

通过若干步可重复的运算来计算复杂问题的方法。

P1192 台阶问题

洛谷链接:P1192 台阶问题

令 \(a_i\) 为到达第 \(i\) 级台阶的方案数,对于每一个 \(a_i\),我们可以枚举 \(a_{i-1}\) 的方案数。

由此我们可以得到递推式:
\(a_0=1\);
\(a_i=\sum_{j=1}^{min(i,k)} a_{i-j}\)。

完整代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e5+3;
int n,k;
long long a[mod];
signed main(){
	cin>>n>>k;
	a[0]=a[1]=1;
	for(int i=2;i<=n;i++){
		if(i<=k)a[i]=(a[i-1]*2)%mod;
		else a[i]=(a[i-1]*2-a[i-k-1])%mod;
	}
	cout<<(a[n]+mod)%mod<<endl;//别忘了加上再模一次
	return 0;
}

贪心

  • 每次做出一个选择后将原问题转化为相似的、规模更小的子问题求解。

  • 证明时一般先假设所有的最优解都不包括这个局部最优解,然后将其中的一部分替换为该局部选择使得答案不劣。重复上述过程直至找到答案。

例题:分数背包

\(n\) 个物品,第 \(a_i\) 个物品的体积为 \(v_i\) 价值为 \(w_i\)。我们可以对物品进行切割,如果切割出的体积为 \(x\),则其价值为 \(w_i × (x/v_i)\),求体积不超过 \(m\) 的物品的最大价值和。

每次取性价比最大的物品,所以按照 \(w_i / v_i\) 排序即可。(具体证明见 PPT)

事实上这道题还可以用类似找中位数的方法直接 O(n) 计算答案

例题:\(k\) 叉哈夫曼树

\(n\) 个权值非负的元素,每次可以合并其中不超过 \(k\) 个元素(和合并果子有点类似,但是只能合并 \(2\) 个数),合并后新产生的元素为这些元素之和,并产生同样数值的代价。求将这些元素合并成一个的代价。

  • 做法
    补 \(0\) 到使 \(n-1\) 是 \(k-1\) 的倍数,然后每次取最小的 \(k\) 个合并(小的数合并多次,大的数少合并几次)。

  • 证明
    假设一定存在最优解不包含该决策,那么假设存在儿子个数不为 \(k\) 的非叶子节点,可以将深度大的叶子补到深度小的空位上;如果没有一个非叶子节点儿子是前 \(k\) 小的,可以将一个前 \(k\) 小的与一个深度最大的节点替换。

CF632C The Smallest String Concatenation

洛谷链接:CF632C The Smallest String Concatenation

用手写 cmpsort 就简单的解决了。

#include <bits/stdc++.h>
using namespace std;
string s[3000000];

bool cmp(string a,string b){//手写 cmp 比较器
	return a+b<b+a;//比较两种拼接方式的大小
}

int n;
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>s[i];
	sort(s+1,s+n+1,cmp);
	for(int i=1;i<=n;i++) cout<<s[i];
	return 0;
}

二分

标签:格子,int,训练营,路径,合并,交集,枚举,CSP,刷题
From: https://www.cnblogs.com/CheZiHe929/p/17578366.html

相关文章

  • 「赛后总结」20230724 CSP 模拟赛
    「赛后总结」20230724CSP模拟赛点击查看目录目录「赛后总结」20230724CSP模拟赛总结。题解T1最长上升子序列ARC125C思路代码T2独特序列ARC125D思路代码T3最大GCDARC126C思路代码T4连续子段ARC126D思路代码想听歌,想看巨人,但是没有条件。总结。rk1三个首杀,前......
  • 济南CSP-J刷题营集训
    Day1比赛T1方差求和可以用前缀和。求平均值时,特判是否整除而输出结果。求方差,我们直接用他给的公式以分数形式算出结果,维护两个分子和分母,通分相减后特判输出。注意要输出最简分数,所以我们用\(\textgcd\)约分。代码:#include<bits/stdc++.h>#definegtgetchar#define......
  • CSP 模拟 4
    今日推歌:SerenadeinG‘EinekleineNachtmusik’K525-WolfgangAmadeusMozart今天比赛直接搬的ARC125,126的CD题,那这样我也能出模拟赛(但是为什么HZOI2022都不写比赛题解,差评今天被HZOI2023,2024薄纱,我直接退役得了T1最长上升子序列考虑一个明显字典序不是......
  • 济南 S NOIP 刷题实战梳理营游记
    前言期末砸力。这次暑假去两个营,一个在烟台,一个在青岛。在烟台的都是学算法,扔到目录里了,这篇文章就是来讲济南营的。一共十二天,每天上午八点到十二点打比赛,然后吃饭,然后讲题。Day-1\(6h\)的大巴,绷不住了,中途在潍坊西休息,热死了。到了济南,住在酒店旁边,楼下全是吃的,很赞。......
  • 代码随想录算法训练营第三十六天| 198.打家劫舍 213.打家劫舍II 337.打家劫舍III
     198.打家劫舍 要求:给定一个nums,要求取得最大值,但是不可以选择两个相邻的数dp定义:dp[n],取到第N个数字的时候,最大值递推公式:取:nums[i]+dp[j-2]不取:nums[i-1];代码:1//在两个数字不相邻的情况下,得到的最大金额2//思路:3//dp[n]第N个数字时的最大金额数4......
  • CSP模拟3 <反思>
    t3:不要随便用mapt4:代码转移要删全首先考虑暴力,类似线段树,首先你要先dfs出每个节点子树的左右节点,然后修改查询时要考虑左儿子右边界是否大于查询左边界,右儿子左边界是否小于查询有边界,进行\(dfs\)\((46pts)\)点击查看代码#include<bits/stdc++.h>#defineintlonglongu......
  • CSP 模拟 3
    今天感觉很热,但是天气转凉的时候我也该退役了吧。今日推歌:透明哀歌-n-buna/Gumiecho-Crusher-P/GumiEnglish歌词Theclockstoppedticking,时钟停止发出嘀嗒声Foreverago.在很久以前HowlonghaveIbeenup?我究竟醒来了多久?Idon'tknow.我不知道Ican't......
  • CSP 模拟 2
    感觉像是noi模拟赛多了个pT1F咋做都行,但是考场上的正确做法被后来优化RE了,痛失60pts其中一种做法是考虑只有\(a_1\oplusb_i\)有可能成为答案,然后验证即可T2S定义dp状态\(f_{i,j,k,0/1/2}\)为用了\(i\)个红球,\(j\)个绿球,\(k\)个红球,并且最后一位是什么球......
  • 2023牛客暑期多校训练营2 补题
    D.TheGameofEating题意:有n个人和m道菜,每个人对每个菜的都有一个喜好度a[i][j],所有人都知道其他人的喜好度,现在需要上k道菜,从1,2...,n,1,2.....的顺序来选,如果每个人都只考虑自己的喜好,问最后哪些菜会被端上来Solution我们考虑到所有人都知道其他人的喜好度,也就是说,假设当前要选......
  • P7074 [CSP-J2020] 方格取数 题解
    题目:题目描述设有n*m 的方格图,每个方格中都有一个整数。现有一只小熊,想从图的左上角走到右下角,每一步只能向上、向下或向右走一格,并且不能重复经过已经走过的方格,也不能走出边界。小熊会取走所有经过的方格中的整数,求它能取到的整数之和的最大值。输入格式第一行有两个整......