Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)

2023-10-19 02:59

本文主要是介绍Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)

A. Even Subset Sum Problem

  • 题意:这一题就是给一个序列,问能这个序列的子集的和,能否为偶数

  • 代码

#include<iostream>
#include<vector>
using namespace std;const int Len = 1e6 + 5;int main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);//freopen("A.txt","r",stdin);int t;cin >> t;while(t --){int n;cin >> n;int ar[n + 5];for(int i = 1; i <= n; i ++) cin >> ar[i];if(ar[1] & 1){if(n < 2) cout << -1 << endl;else if(ar[2] & 1)  cout << 2 << endl << 1 << ' ' << 2 << endl;else cout << 1 << endl << 2 << endl;}elsecout << 1 << endl << 1 << endl;}return 0;
}
  • 收获:明白 了 & 操作符号的意思

B. Count Subrectangles

  • 题意:给两个数组a【】、b【】,又有一个 c[ ][ ] 二维数,在这个二维数组中的元素为:c[ i ][ j ] = a[ i ] * b[ i ],
    问面积为k的矩形在c[ ][ ]中有多少个(⚠️ :构成这个矩形的所有元素必须是全由1组成)

  • 思路: ----> ⬇️方

  • 代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
using namespace std;
/** 思路:这一题的思路:就是遍历所有的 k 的所有除数对,进行找答案。*      但是直接暴力找答案明显会时间超时,所以这一题的难点就是 “预处理”,*      在预处理的的时:*      1. 首先我们一定要明白题目上给的一些 数据 的用途,*      首先我们考虑 在数组a中在假设区间[x, y]内全部是1,假设这个时候数组b中全部为 1,*      我就一定可以确定c数组中,对应的在 x行到y行 这些行必定都是由 1 组成,*      那么说明我们可以把c中 x到y行之间的距离预处理下来,这些距离就是可以作为矩形的高度*      而对于一个 在数组a中的这个[x, y] 区间,我们可以统计出来, 高度为h(h属于[1, y - x + 1])*      的方案个数.*      2. 我们假设 a数组中的数全部是1,那么我在考虑 b数组连续为1的区间[i, j], 那么对应于c数的中的*      i 到 j 列之间的每一列都是由 1 组成,同样我们可以预处理出所有的宽度 w 的方案个数*      3. 之前我们在考虑 一个数中的 连续为1的情况总是 把另一个数组中的 元素全部当成1来处理,*      但这是与题上的实际情况不符合的,但是我们的统计确实有用的,我们可以做一个假设来考虑,*      我们假设要组成一个 高h = 2, 宽 w = 3 的一个矩形,那么在数组a中连续两个1,在c中所对应的行,*      与在数组b中连续3个1 在c中所对应的列, 在连续的列与行的交叉处我们一定可以保证 这个2x3的矩形交叉的区域全部*      是有1 组成,就是我要求的这个矩形,,剩下的就是看代码列。。。。*/
#define ll long long vector<ll> gao(vector<int> a)
{int n = a.size();int i = 0;vector<ll> res(n + 1);while(i < n){if(a[i] == 0){i ++; continue;}//统计连续1的个数int j = i;while(j < n && a[j] == 1){j ++;}//统计每种大小的高(或宽)度的的个数for(int len = 1; len <= j - i; len ++){res[len] += j - i - len + 1;        //⚠️  j - i - len + 1 是长度为 len 大小的个数,在长度 为 j - i 的连续1子串中}i = j;}return res;
}int main()
{ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);//freopen("A.txt","r",stdin);int n,m,k;cin >> n >> m >> k;vector<int> a(n);vector<int> b(m);for(auto &x : a)cin >> x;for(auto &y : b)cin >> y;ll ans = 0;//预处理操作auto ha = gao(a);auto wb = gao(b);//遍历每一种 size = k 的矩形for(int i = 1; i <= n; i ++){if(k % i == 0 && k / i <= m){int h = i, w = k / i;ans += ha[h] * wb[w];}}cout << ans << endl;return 0;
}

C. Unusual Competitions(前缀差值)

  • 题意:给一个仅由 “(”和 “)”组成的括号序列 例如:“ ) ) ( ( ( ) ) (”,问最少需要需要变换让左右的括号一一对应,这里的变换指的是:选择一段在括号序列的区间 [ l , r ] , 可以把这个区间内的括号,任意交换顺序,但不能改变左右的括号的数量
  • 思路:
    • 分析如果我们想把所有的括号匹配,首先的前提就是,在所给的序列中左右括号的数列要相等,若果不想等直接输出-1, 如果先等变换的最小长度为最大长度是,我们选择整个序列进行变换,就一定能够得到答案
    • 对于这一看答案上:引入了一个前缀的东西,这个“前缀差值东西”: pre[ i ] 是 从 1 ~ i 位置 左括号的数量 - 右括号的数量 的差值,这个差值可以模仿 前缀和来理解,我在结合这个图理解一下就行了
    • 其实除了 上面的方法我们能把一些东西都明白,就容易了 其实我们可以 从 左到右 对这个序列,进行考虑,如果我们一开始 遇到的是一个匹配好的序列,那么我可以直接跳过这个序列,对剩下的序列进行讨论,而遇到不配的序列,我们就从左到右找到最短的左右括号数量相同的序列,根据贪心的思想直接变换这个字段就行了(这样得剩下的仍是 左右括号数量相同),反过来想如果我们 不变换这一段的部分行吗??

在这里插入图片描述
初始序列:Given sequence was ( ) ) ( ( ) ) ) ( ) ( (
在这里插入图片描述

变化后的序列:After reshuffling 2 segments of total length 8, we can get a right bracketed sequence: ( ) ( ) ( ( ( ) ( ) )

  • 代码
#include<iostream>
#include<vector>
using namespace std;const int Len = 1e6 + 5;
char ar[Len];
int pre[Len];       //pre 数组是前缀差额, pre[i]  的值为:在前i个字符中, 右括号‘(’ 的数量 - 左括号的数量‘)’int main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);//freopen("A.txt","r",stdin);int n;cin >> n;char ch;int op = 0, cl = 0;int last = 0;int ans = 0;for(int i = 1; i <= n; i ++){cin >> ch;if(ch == '('){op ++;pre[i] = pre[i - 1] + 1;}else{cl ++;pre[i] = pre[i - 1] - 1;}if(pre[i] == 0){if(pre[i - 1] < 0){ans += i - last; }last = i;}}if(op == cl)cout << ans << endl;elsecout << -1 << endl;return 0;
}
  • 收获:知道可以用前缀差值这个东西,可以用来处理对序列的操作

这篇关于Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/236850

相关文章

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

Open a folder or workspace... (File -> Open Folder)

问题:vscode Open with Live Server 时 显示Open a folder or workspace... (File -> Open Folder)报错 解决:不可以单独打开文件1.html ; 需要在文件夹里打开 像这样

android java.io.IOException: open failed: ENOENT (No such file or directory)-api23+权限受权

问题描述 在安卓上,清单明明已经受权了读写文件权限,但偏偏就是创建不了目录和文件 调用mkdirs()总是返回false. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_E

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;