【题解报告】ZJNU综合训练(2021.1.26)

  • B
  • C
  • D
  • F
  • H
  • I
  • J
  • M
  • 综合训练 ZJNU综合训练(2021.1.26)
    B:DP+搜索 | CF 1057C
    C:组合数学+dp | CF 1422C
    D:思维 | CF 1185D
    F:树形DP | CF 219D
    H:暴力+数学 | CF 1096C
    I:思维+DP | CF 1381B
    J:DP | CF1452D
    M:博弈 | CF 197A

B

  • 有 n n n 盒糖果并排放,每盒有数量 r i r_i ri​ ,里面颜色为 c i c_i ci​。
  • 如果吃糖,必须在该位置的糖全部吃完,且必须比上一次吃得数量多,且必须与上一次吃的糖的颜色不一样。
  • 每次向相邻方向走一格的时间花费为 1 1 1,吃糖不花费时间。
    起点在 s s s,问你至少吃 k k k 颗糖最少花费时间为多少。

  • 题目要求真地多,而且我开始还读错题意了。。
    设 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示你现在在位置 i i i 且吃了该位置的糖,花了 j j j 时间的最多吃糖数。
    为什么可以这么设呢?因为你每次吃糖一定是吃完的,你中间如果走过去没有吃得话,其实是为了走到目的地然后吃,所以设的不是你目前的位置,而是你目前吃完糖的位置
  • 转移条件也很简单,满足糖果颜色不同、数量要更多就行了。
    注意,时间上限是多少? n 2 n^2 n2,因为你不可能没吃糖,经过同一个点两次。

时间复杂度: O ( n 4 log ⁡ n ) O(n^4\log n) O(n4logn)

const int MAX = 55;
int n,s,k;
int r[MAX];
string c;
int dp[MAX][MAX*MAX];int main()
{cin >> n >> s >> k;for(int i = 1;i <= n;++i)cin >> r[i];cin >> c;c = " " + c;memset(dp,-1,sizeof(dp));priority_queue<pair<int,int> >Q;for(int i = 1;i <= n;++i){dp[i][abs(i-s)] = r[i];Q.push(make_pair(-(abs(i-s)),i));}while(!Q.empty()){int d = -Q.top().first;int x = Q.top().second;Q.pop();if(dp[x][d] >= k){cout << d;return 0;}for(int i = 1;i <= n;++i){if(c[x] != c[i] && r[i] > r[x] && dp[i][abs(i-x)+d] < dp[x][d] + r[i]){dp[i][abs(i-x)+d] = dp[x][d] + r[i];Q.push(make_pair(-(abs(i-x)+d),i));}}}cout << -1;return 0;
}

C

  • 给你一个长度为 1 0 5 10^5 105 的数字串。
    问你,中间连续删掉一段数字之后,剩下的数字头尾相接,形成删数。问你所有不同的删法后,所拼接出来的删数的和取模 998244353 998244353 998244353 是多少。
  • 比如 107 107 107,删掉中间连续一段之后会变成 07 、 17 、 10 、 7 、 1 、 0 07 、 17、 10、 7、 1、 0 07、17、10、7、1、0,他们的和为 42 42 42

  • 把数字拼接起来之后再算怎么搞都是搞不出来的、、我们按头和尾来考虑。
    如果他们俩能连接起来,我们给他们连一条线。下面的 + + +号表示把他们收尾拼接。
    比如 ϕ + 07 = 07 \phi +07=07 ϕ+07=07、 ϕ + ϕ = 0 \phi+\phi=0 ϕ+ϕ=0、 1 + 7 = 17 1+7=17 1+7=17
  • 考虑每一串头和每一串尾到底对答案作出多少贡献。
    注意:头的拼接还要考虑拼接后相当于头的数字增加了 1 0 k 10^k 10k
  • 尾的收益:最长的尾只贡献 1 1 1次,次长的贡献 2 2 2次等
    尾的收益比较好算,单个串的数字好算,单个串的贡献次数也好算。
  • 头的收益:
    (1) ϕ \phi ϕ 的贡献为 1 1 1 次和长度为 2 2 2 的串拼接, 1 1 1 次为和长度为 1 1 1 的串拼接, 1 1 1 次和长度为 0 0 0 的串拼接,它的贡献就是 0 × ( 1 0 2 + 1 0 1 + 1 0 0 ) 0\times(10^2+10^1+10^0) 0×(102+101+100)
    (2) 1 1 1 的贡献为 1 1 1 次和长度为 1 1 1 的串拼接, 1 1 1 次和长度为 0 0 0 的串拼接,它的收益就是 1 × ( 1 0 1 + 1 0 0 ) 1\times(10^1+10^0) 1×(101+100)
    (3)对于某一个头串,它的贡献为 它 本 身 × p r e [ x ] 它本身\times pre[x] 它本身×pre[x] ,其中 p r e [ x ] = 1 0 x + 1 0 x − 1 + ⋯ + 1 0 0 pre[x]=10^x+10^{x-1}+\cdots+10^0 pre[x]=10x+10x−1+⋯+100。这个 x x x 取原串长减去该头串长再减一。

时间复杂度: O ( l o g 10 S ) O(log_{10}S) O(log10​S)

/*_            __   __          _          _
| |           \ \ / /         | |        (_)
| |__  _   _   \ V /__ _ _ __ | |     ___ _
| '_ \| | | |   \ // _` | '_ \| |    / _ \ |
| |_) | |_| |   | | (_| | | | | |___|  __/ |
|_.__/ \__, |   \_/\__,_|_| |_\_____/\___|_|__/ ||___/
*/
char ss[MAX];
ll pre[MAX];
void init(int x){pre[0] = 1;ll base = 10;for(int i = 1;i <= x;++i){pre[i] = (pre[i-1] + base) % MOD;base = base * 10 % MOD;}
}
int main()
{init((int)1e5+50);scanf("%s",ss);int len = strlen(ss);ll sum = 0;ll base = 1;ll tmp = 0;for(int i = len-1;i >= 1;--i){tmp = (base * (ss[i]-'0') % MOD + tmp) % MOD;sum = (sum + tmp * i % MOD) % MOD;base = (base * 10) % MOD;}tmp = 0;base = 1;for(int i = 0;i < len-1;++i){tmp = (tmp * 10 % MOD + (ss[i]-'0')) % MOD;sum = (sum + tmp * pre[len-i-2] % MOD) % MOD;base = (base * 10) % MOD;}printf("%lld",sum);return 0;
}

D

  • 问你对于一个序列,是否可以删掉一个数字后,其他数字成等差,问你删掉哪一个。
  • 序列先排序,再考虑删头或者删尾或者删中间。
    删中间的话:要删除的那个数字的序号一定是 该位置之后的数字减去该位置之前的数字的和最小
    考虑一个等差 5 、 10 、 15 、 20 、 25 5、 10、 15、 20、 25 5、10、15、20、25
    如果要删中间,你多余的数字应该要放在这些数字的中间
    5 、 10 、 15 、 18 、 20 、 25 5、 10、 15、 18、 20、 25 5、10、15、18、20、25
    此时明显 20 − 18 + 18 − 15 = 20 − 15 = 5 20-18+18-15=20-15=5 20−18+18−15=20−15=5 是所有里面最小的,因为其他的数字 15 − 5 = 10 15-5=10 15−5=10 明显是两倍等差。

F

  • 给你一个树,但是树的边是单向的。
    你要选择首都的位置,要修改一些道路的朝向,使得首都能够到达所有的位置。
    问你最少修改多少条路,以及首都的所有可选位置。
  • 树形 D P DP DP。设 d p [ x ] dp[x] dp[x] 表示在 x x x 位置处选择首都的话,需要改多少条路。
    虽然这个 d p [ x ] dp[x] dp[x] 我们是直接算不出来的,但是我们知道相邻两个位置的 d p dp dp 值的大小关系
  • 这样就能算出哪个节点的 d p dp dp 值相对最小,然后以该节点作为起点进行 d f s dfs dfs,查看需要修改几条边就行了。
/*_            __   __          _          _
| |           \ \ / /         | |        (_)
| |__  _   _   \ V /__ _ _ __ | |     ___ _
| '_ \| | | |   \ // _` | '_ \| |    / _ \ |
| |_) | |_| |   | | (_| | | | | |___|  __/ |
|_.__/ \__, |   \_/\__,_|_| |_\_____/\___|_|__/ ||___/
*/
vector<pair<int,int> >V[MAX];
int dp[MAX];
int mn,id;
void dfs(int u,int fa){     /// 跑dpif(dp[u] < mn){mn = dp[u];id = u;}for(auto it : V[u]){int v = it.first;int w = it.second;if(v == fa)continue;if(w == 1)dp[v] = dp[u] + 1;else dp[v] = dp[u] - 1;dfs(v,u);}
}
int ans;
void dfs2(int u,int fa){    // 跑最小修改路径数量for(auto it : V[u]){int v = it.first;int w = it.second;if(v == fa)continue;if(w == -1)ans++;dfs2(v,u);}
}
int main()
{int n;scanf("%d",&n);for(int i = 1;i < n;++i){int ta,tb;scanf("%d%d",&ta,&tb);V[ta].push_back(make_pair(tb,1));V[tb].push_back(make_pair(ta,-1));}mn = 0;id = 1;dfs(1,1);dfs2(id,id);printf("%d\n",ans);for(int i = 1;i <= n;++i){if(dp[i] == dp[id])cout << i << " ";}return 0;
}

H

  • 问你,最少正几边形,你通过顶点连接能够得到 d d d 的角度(角度制),该角度为 1 ∼ 180 1\sim180 1∼180的整数。
  • 圆周角所对的弧长相等的话,圆周角是相同的。因此一个正 n n n 边形,算出一份圆周角是多少度,然后每次暴力枚举份数 1 ∼ n − 2 1\sim n-2 1∼n−2,查看是不是整数度数即可。
int mn[MAX];int main()
{int T;cin >> T;while(T--){int n;cin >> n;int mn = INF;for(int i = 3;i <= 700;++i){double deg = (180.0*i-360)/(1.0*i)/(1.0*i-2);for(int j = 1;j <= i-2;++j){double de = deg * j;if(fabs(de-n)<EPS)mn=min(mn,i);}}if(mn == INF)cout << -1 << endl;else cout << mn << endl;}return 0;
}

I

  • m e r g e ( A , B ) merge(A,B) merge(A,B) 函数表示每次取 A 、 B A、B A、B 序列的开头较小的元素,然后把该位置的元素拿出来,放在集合的尾。如果有一个序列是空的话,直接取非空序列。
    比如 m e r g e ( { 3 , 2 } , { 1 , 4 } ) = { 1 , 3 , 2 , 4 } merge(\{3,2\},\{1,4\})=\{1,3,2,4\} merge({3,2},{1,4})={1,3,2,4}
    给定一个 2 n 2n 2n 个元素的全排列。问该全排列是否能通过 m e r g e ( A , B ) merge(A,B) merge(A,B),且 ∣ A ∣ = ∣ B ∣ = n |A|=|B|=n ∣A∣=∣B∣=n得到。

  • 非常巧妙的一题。
    (1)对于目前的最大元素 2 n 2n 2n ,假设该元素原来是在 A A A 里面,那么该位置之后的所有数字一定全属于 A A A 序列。然后我们把这些数字给拿出来。
    (2)对于剩下的数字,有最大元素 p p p ,该位置到末尾的位置一定全属于 A A A 或 B B B 序列。
    (3)重复上述步骤,我们就得到了一段一段的序列,每一段必须都属于 A A A 或者 B B B 序列。
    (4)怎么求是否能存在 ∣ A ∣ = ∣ B ∣ = n |A|=|B|=n ∣A∣=∣B∣=n 呢?设一个 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示目前处理到第 i i i 段,若 d p [ i ] [ j ] = 1 dp[i][j]=1 dp[i][j]=1 则表示目前我们能拿到长度为 j j j 的段。最后看 d p [ 段 数 ] [ n ] = 1 o r 0 dp[段数][n]=1\ or\ 0 dp[段数][n]=1 or 0就可以了。
    时间复杂度: O ( n 2 ) O(n^2) O(n2)
int aa[MAX];
int pos[MAX];
bool use[MAX];
int shu[MAX];
int dp[MAX][MAX];
int main()
{int T;cin >> T;while(T--){int n;cin >> n;int ed = n * 2;for(int i = 1;i <= ed;++i){cin >> aa[i];pos[aa[i]] = i;use[aa[i]] = 0;}int you = ed;int last = ed;int cnt = 0;while(you){while(use[last])last--;for(int i = pos[last];i <= you;++i)use[aa[i]] = 1;shu[++cnt] = you - pos[last] + 1;you = pos[last] - 1;}for(int i = 1;i <= cnt;++i)for(int j = 0;j <= ed;++j)dp[i][j] = 0;dp[0][0] = 1;for(int i = 1;i <= cnt;++i){for(int j = 0;j <= ed;++j){if(j >= shu[i])dp[i][j] |= dp[i-1][j-shu[i]];dp[i][j] |= dp[i-1][j];     /// 这个不要忘记转移}}if(dp[cnt][n])puts("YES");else puts("NO");}return 0;
}

J

  • 有 n + 1 n+1 n+1个点,第 0 0 0个点的位置为 0 0 0,第 i i i 个点的位置为 i i i。
    对于中间 1 ∼ n 1\sim n 1∼n的点,每个点都有 1 2 \frac{1}{2} 21​ 的概率放置一个信号塔,该点为 i i i ,信号塔的强度如果为 p p p ,则他能覆盖到 j j j 点的条件是 ∣ i − j ∣ < p |i-j|<p ∣i−j∣<p
    所有塔的信号强度是你自己调整的,可以都不同。
    求:有多少的概率使得你可以调整所有信号塔,使得 1 ∼ n 1\sim n 1∼n的所有点都只被一个信号塔的信号覆盖,且 0 0 0 和 n + 1 n+1 n+1 没有被信号覆盖

  • 可以想到,不管信号强度为多少,该信号塔能覆盖到的数量一定是奇数
    题目就转变为 d p ( i ) 2 n \frac{dp(i)}{2^n} 2ndp(i)​,其中 d p ( i ) dp(i) dp(i) 表示 i i i 能被拆成奇数的方案个数。(注意这里是顺序可换的方案)
    比如 d p ( 3 ) = 2 dp(3)=2 dp(3)=2,因为 3 = 1 + 1 + 1 = 3 3=1+1+1=3 3=1+1+1=3
    考虑状态转移方程就可以了:
    d p ( i ) = d p ( i − 1 ) + d p ( i − 3 ) + ⋯ + d p ( ( x − ( 2 k + 1 ) ) > 0 ) dp(i)=dp(i-1)+dp(i-3)+\cdots+dp((x-(2k+1))>0) dp(i)=dp(i−1)+dp(i−3)+⋯+dp((x−(2k+1))>0)
    就用一个前缀和 p r e [ x ] = d p ( x ) + d p ( x − 2 ) + ⋯ pre[x]=dp(x)+dp(x-2)+\cdots pre[x]=dp(x)+dp(x−2)+⋯ 就可以了。

时间复杂度: O ( N ) O(N) O(N)

/*_            __   __          _          _
| |           \ \ / /         | |        (_)
| |__  _   _   \ V /__ _ _ __ | |     ___ _
| '_ \| | | |   \ // _` | '_ \| |    / _ \ |
| |_) | |_| |   | | (_| | | | | |___|  __/ |
|_.__/ \__, |   \_/\__,_|_| |_\_____/\___|_|__/ ||___/
*/
ll dp[MAX];
ll pre[MAX];        /// pre[i] = dp[i] + dp[i-2] + dp[i-4]...
int main()
{int n;cin >> n;dp[0] = 1;pre[0] = 1;dp[1] = 1;pre[1] = 1;for(int i = 2;i <= n;++i){dp[i] = pre[i-1];pre[i] = (pre[i-2] + dp[i]) % MOD;}cout << dp[n] * inv(qpow(2,n)) % MOD;return 0;
}

M

  • 一张 n × m n\times m n×m的桌子,有无穷多的盘子,盘子半径都为 r r r
    两个人轮流放盘子,盘子不能重叠,不能边超出桌子。
    问你先手必胜还是后手必胜

  • 这题真不是水题也不是 B U G BUG BUG 题呀。。
    如果先手第一个盘子都放不下,那肯定是后手赢了。
    否则,先手第一个盘子放在该桌子的正中心处
    这样,构造除了一个中心对称图形。后手不论怎么放,先手都放在该位置的中心对称位置处。这样,不论后手怎么放,先手都能有位置放(易证),因为每一次先手放置的时候该图都是中心对称图形。

【题解报告】ZJNU综合训练(2021.1.26)相关推荐

  1. Leetcode刷题 2021.02.26

    Leetcode刷题 2021.02.26 Leetcode1178 猜字谜 Leetcode869 重新排序得到 2 的幂 Leetcode1676 二叉树的最近公共祖先 IV Leetcode11 ...

  2. 前端面试题笔记 2021.8.26

    2021.8.26学习笔记 如果需要匹配包含文本的元素,用下面哪种方法来实现? A. text() B. contains() C. input() D. attr(name) 正确答案: B tex ...

  3. 2015浙江财经大学ACM有奖周赛(一) 题解报告

    2015浙江财经大学ACM有奖周赛(一) 题解报告 命题:丽丽&&黑鸡 这是命题者原话. 题目涉及的知识面比较广泛,有深度优先搜索.广度优先搜索.数学题.几何题.贪心算法.枚举.二进制 ...

  4. 【报告分享】2021开放数字资产价值报告:数字化孕育新的发展动能.pdf(附下载链接)...

    大家好,我是文文(微信号:sscbg2020),今天给大家分享Fastdata极数于2021年8月份发布的报告<2021开放数字资产价值报告:数字化孕育新的发展动能.pdf>.关注数字资产 ...

  5. 【报告分享】2021新中产人群洞察报告.pdf(附下载链接)

    大家好,我是文文(微信号:sscbg2020),今天给大家分享QuestMobile于2021年8月份发布的<2021新中产人群洞察报告.pdf>.新中产人群年龄在25-40岁之间,身处三 ...

  6. 【报告分享】2021年Z世代“潮力量”洞察报告.pdf(附下载链接)

    大家好,我是文文(微信号:sscbg2020),今天给大家分享Mob研究院于2021年7月份发布的报告<2021年Z世代"潮力量"洞察报告.pdf>.Z世代" ...

  7. 【报告分享】2021年微信视频号半年度生态趋势调查报告.pdf(附下载链接)

    大家好,我是文文(微信号:sscbg2020),今天给大家分享友望数据于2021年7月份发布的<2021年微信视频号半年度生态趋势调查报告.pdf>,本报告选取了2021年1月-5月有持续 ...

  8. 【报告分享】2021快手内容生态半年报:从心出发.pdf(附下载链接)

    大家好,我是文文(微信号:sscbg2020),今天给大家分享快手大数据研究院于2021年8月份发布的<2021快手内容生态半年报.pdf>,本报告以"从心出发"为主题 ...

  9. 【报告分享】2021上半年短视频及电商生态研究报告.pdf(附下载链接)

    大家好,我是文文(微信号:sscbg2020),今天给大家分享飞瓜数据于2021年7月份发布的<2021上半年短视频及电商生态研究报告.pdf>,关注抖音.短视频.兴趣电商.直播电商等的伙 ...

最新文章

  1. centos 6.3 安装reids
  2. 如何禁用UITableView选择?
  3. ”A page can have only one server-side Form tag“错误
  4. mysql char null_关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别...
  5. N-Gram的数据结构
  6. java简单计算机程序_JAVA程序编的简单计算器程序??
  7. 把庞大的 npm script 拆到单独文件中
  8. 一个故事告诉你,数据分析如何给企业带来价值
  9. 小米 11 不送充电器;苹果已修复 iCloud 登录激活问题;Ruby 3.0.0 发布|极客头条...
  10. JQuery,ajax,jsonp 跨域访问
  11. Linux 操作系统课程设计
  12. kettle连接ClickHouse
  13. 一只Quant菜鸟的修行之路
  14. 用计算机如何算瓷砖菱形加工,瓷砖菱形铺贴怎么计算面积
  15. 【干货】常用的14个获取数据的网站。
  16. 解决Mac无法睡眠问题
  17. Chrome播放视频时只有声音没有画面
  18. 二维码解码器Zbar+VS2010开发环境配置
  19. 计算机常用英语单词1500
  20. 消灭该死的重复 下(1)布尔运算 boolean

热门文章

  1. Android Debug Bridge (ADB)
  2. 二次开发发票管理软件应该注意的事项
  3. 计算机毕业设计Java租车网站(源码+系统+mysql数据库+Lw文档)
  4. 用matlab验证罗尔定理,高等数学一习题3.1答案
  5. 硅切片切割液消泡剂轻松取而代之别的除泡方法
  6. 光伏数据采集方案——逆变器,电表,气象站
  7. 美团外卖手机网页版数据加密解析
  8. 1-3NF,BCNF,最小依赖集,模式分解,判断是否为无损分解
  9. 无人机拍滑雪不够酷,用GoPro Omni VR如何?
  10. 文章聚合怎么进行文章伪原创