当前位置: 首页 > news >正文

codeforces 补题1

题目:D. Retaliation

https://codeforces.com/contest/2117/problem/D

大意:

在一次操作中,可以完成以下两项操作之一:

  1. 对于 a 中的每个索引 i ,将 ai 减少 i 。
  2. 对于 a 中的每个索引 i ,将 ai 减少 n−i+1 。

判断是否能使数组中的每一个元素都等于0,如果可以,输出“Yes”,反之输出“No”.

思路:

这是一道数学题,假设要使数组中的每一个元素都等于0需要执行“操作1”x次,“操作2”y次,因为每个元素都等于0,所以数组前两个元素一定等于0,数组前两个元素的值均已知,列出方程组可以解出x和y的值,判断x和y的值是否合理,是否也能使其他元素都等于0。

代码:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
using ll = long long;
void solve() {int n; cin >> n;vector<int>nums(n + 1, 0);for (int i = 1; i <= n; i++) {cin >> nums[i];}int yj = (2 * nums[1] - nums[2]) % (n + 1);if (yj != 0) {//判断x和y是否能被整除cout << "NO" << endl;return;}int y= (2 * nums[1] - nums[2]) / (n + 1);int x = y - nums[1] + nums[2];//利用nums[1]和nums[2]表示x和y的值if (x < 0 || y < 0) {//如果x或者y小于0,则该值不合理,输出Nocout << "NO" << endl;return;}for (int i = 3; i <= n; i++) {//检查除nums[1]和nums[2]以外,其他元素是否也等于0if (nums[i] - x * i - y * (n - i + 1) != 0) {cout << "NO" << endl;return;}}cout << "YES" << endl;return;
}signed main() {int t; cin >> t;while (t--)solve();return 0;
}/*如果题目是对一个数组同时进行某些操作,就可以从部分入手,先利用部分已知量来表示未知量,
然后把表示出来的未知量套入数组中观察是否数组中的每一个元素都符合条件。*/

题目:B. Skibidus and Fanum Tax (hard version)

https://codeforces.com/contest/2065/problem/C2

大意:

给定数组a,b,能否对数组a任意元素进行操作,使得得到的数组a,非递减排列,即对于任意的i都满足a[i]<=a[i+1],若能满足输出“YES”,反之输出“NO”。

对数组a进行的操作:a[i]=b[j]-a[i],其中j为b数组任意一个元素的下标。

思路:

若想使a[i]<=a[i+1],成立,a[i+1]应该在不超过a[i+2]的范围的条件下取得最大值,这样a[i]的条件才能更加宽松。首先先对b数组从小到大进行排序,如果是a数组的最后一个元素a[n-1]想取最大值,a[n-1]=max(a[n-1],b[m-1])。如果不是最后一个元素有以下几种情况:

1.如果找不到b[j]使得b[j]-a[i]为不大于a[i+1]的最大值(找不到最大的b[j]使得b[j]-a[i]<=a[i+1]),并且a[i]>a[i+1],这种情况出现,数组不可能按照非递减排列。

2.如果能找到最大的b[j]使得b[j]-a[i]<=a[i+1],并且a[i]>a[i+1],这时候的a[i]只能为b[j]-a[i];

3.如果能找到最大的b[j]使得b[j]-a[i]<=a[i+1],并且a[i]<a[i+1],这时候a[i]=max(b[j]-a[i],a[i]),取较大的数,为下一次比较铺路。

代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<numeric>
#include<limits>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<iomanip>
#include<sstream>
using namespace std;
using ll = long long;
void solve() {
//输入int n, m;cin >> n >> m;vector<ll>a(n), b(m);for (int i = 0; i < n; i++)cin >> a[i];for (int j = 0; j < m; j++)cin >> b[j];
//对b按从小到大排序sort(b.begin(), b.end());
//对a[n-1]进行特殊处理,取最大值。a[n - 1] = max(b[m - 1] - a[n - 1], a[n - 1]);
//对其他元素进行处理for (int i = n - 1; i > 0; i--) {
//upper_bound()函数用于寻找不大于a[i]+a[i-1]的最大b[j],注意下标应该-1。int k = upper_bound(b.begin(), b.end(), a[i] + a[i - 1]) - b.begin();
//情况1:找不到b[j],并且前一个大于后一个。if (!k && a[i - 1] > a[i]) {cout << "NO" << endl;return;}
//情况2:找到b[j],并且前一个不大于后一个。else if (k && a[i - 1] <= a[i]) {a[i - 1] = max(a[i - 1], b[k - 1] - a[i-1]);}
//情况3:找到b[j],并且前一个大于后一个。else if (k && a[i - 1] > a[i]) {a[i - 1] = b[k - 1] - a[i-1];}}cout << "YES" << endl;return;}
signed main() {int t; cin >> t;while (t--)solve();return 0;
}

题目:D. Skibidus and Sigma

https://codeforces.com/contest/2065/problem/D

大意:

给定一个二维数组,对数组的每行进行排序,使得其前缀和相加为最大值。

例如:数组:{(4,4),(6,1)}

  • 按{4,4,6,1}排列 ,它的得分是 4+(4+4)+(4+4+6)+(4+4+6+1)=41 。
  • 按{6,1,4,4}排列, 它的得分是 6+(6+1)+(6+1+4)+(6+1+4+4)=39 。

思路:

贪心,对每一行的所有值求和,按照总和从大到小进行排序。然后按题目要求相加即可。

代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
#include<set>
#include<map>
#include<iomanip>
#include<limits>
#include<string>
#include<cstring>
using namespace std;
using ll = long long;//排序规则
bool cmp(vector<ll>& arr1, vector<ll>& arr2) {//注意这里传递参数传的是数组ll sum = accumulate(arr1.begin(), arr1.end(), 0);ll sum1 = accumulate(arr2.begin(), arr2.end(), 0);return sum > sum1;
}void solve() {
//输入ll n, m; cin >> n >> m;vector<vector<ll>>nums(n, vector<ll>(m, 0));for (ll i = 0; i < n; i++) {for (ll j = 0; j < m; j++) {cin >> nums[i][j];}}
//排序sort(nums.begin(), nums.end(), cmp);vector<ll>sum_nums(n * m + 1, 0);ll k = 1;for (ll i = 0; i < n; i++) {for (ll j = 0; j < m; j++) {sum_nums[k] = sum_nums[k - 1] + nums[i][j];//前缀和k++;} }
//将前缀和相加,注意这里accumulate()的使用,accumulate(x.begin(),x.end(),0),这里的0默认是int类型,需要强制转换成ll。ll ans = accumulate(sum_nums.begin(), sum_nums.end(), (ll)0);cout << ans << endl;}
signed main() {ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);int t; cin >> t;while (t--)solve();return 0;
}

题目:E. Skibidus and Rizz

https://codeforces.com/contest/2065/problem/E

大意:

给定0的数量是n,1的数量是m,和k,输出一个字符串使得它的全部字串的max(n-m,m-n)最大值为k。

思路:

思考题,字符串开头用数量多的(0||1)直接填满k,之后10交替就行。

代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<limits>
#include<string>
#include<iomanip>
#include<map>
#include<set>
#include<sstream>
#include<cmath>
using namespace std;
using ll = long long;
void solve() {int n, m, k; cin >> n >> m >> k;string str;
//如果k比n,m都大,直接-1。 如果k比abs(n-m)小,直接-1。if ((k > m && k > n)||(n-m>k)||(m-n>k)) {cout << -1 << endl;return;}else {if (m >= n) {for (int i = 0; i < k; i++) {str += '1';}m -= k;while (m > 0 || n > 0) {if (n > 0) {str += '0';n--;}if (m > 0) {str += '1';m--;}}}else if (m < n) {for (int i = 0; i < k; i++) {str += '0';}n -= k;while (m > 0 || n > 0) {if (m > 0) {str += '1';m--;}if (n > 0) {str += '0';n--;}}}}cout << str << endl;
}
signed main() {int t; cin >> t;while (t--)solve();return 0;
}

题目:C. Sakurako's Field Trip

https://codeforces.com/contest/2033/problem/C

大意:

给定一个数组a,可以进行将索引i和索引n-i+1对应的元素交换,能否通过任意次交换使得a[i]==a[i+1]的次数最少,输出最少次数。

思路:

双指针,看见相等就交换,要不就相等的数量不变,要不数量减一

代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<numeric>
#include<limits>
#include<sstream>
#include<iomanip>
#include<map>
using namespace std;
using ll = long long;
void solve() {int n; cin >> n;vector<ll>nums(n);for (int i = 0; i < n; i++)cin >> nums[i];int left = 1; int right = n - 2;while (left < right) {if (nums[left - 1] == nums[left] || nums[right + 1] == nums[right]) {swap(nums[left], nums[right]);}left++;right--;}int ans = 0;for (int i = 0; i < n-1; i++) {if (nums[i] == nums[i + 1]) {ans++;}}cout << ans << endl;
}
signed main() {int t; cin >> t;while (t--)solve();return 0;
}

题目:D. Kousuke's Assignment

https://codeforces.com/contest/2033/problem/D

大意:

如果有 al+al+1+⋯+ar−1+ar=0 ,则 [l,r] 段被认为是美丽的,计算不重叠的美丽线段的最大数目。

思路:

用map记录每一步sum的值,如果这个值之前遇到过就说明有一段a的元素相加等于0,这时候清空map,如果不清空就会重叠。

代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<limits>
#include<numeric>
#include<cmath>
using namespace std;
using ll = long long;
void solve() {int n; cin >> n;vector<ll>nums(n, 0);for (int i = 0; i < n; i++)cin >> nums[i];map<ll, int>mp;ll sum = 0;int ans = 0;for (int i = 0; i < n; i++) {sum += nums[i];if (mp[sum] == 1||sum==0||nums[i]==0) {ans++;mp.clear();sum = 0;continue;}mp[sum] = 1;}cout << ans << endl;
}
signed main() {int t; cin >> t;while (t--)solve();return 0;
}

http://www.dtcms.com/a/323526.html

相关文章:

  • FAN5622SX 四通道六通道电流吸收线性LED驱动器,单线数字接口 数字式调光, 2.7 → 5.5 V 直流直流输入, 30mA输出FAN5622S
  • 现代数据加密技术:守护数字世界的无形之盾
  • 供应链需求预测项目如何设定合理的KPI、准确率指标(十四)
  • jxWebUI--输入框
  • M8-11读卡器如何通过RS485转Profinet网关在plc写入从站地址
  • 飞书多维表格搭建设备租赁系统-和保养提醒
  • C++ 虚函数、多重继承、虚基类与RTTI的实现成本剖析
  • 云闪付自动签到脚本
  • 线程池与反射
  • 动态规划(三维)直接按照题目条件
  • 基于STM32H5的循环GPDMA链表使用
  • Redis 事务机制
  • java基础(六)jvm
  • Vue3 路由
  • Chaos Monkey 故障注入工具使用介绍
  • Day37--动态规划--52. 携带研究材料(卡码网),518. 零钱兑换 II,377. 组合总和 Ⅳ,57. 爬楼梯(卡码网)
  • Web前端之 ECMAScript6
  • 【ros_humble】3.人脸检测python(服务通讯和参数通讯介绍)
  • 关于Linux软件编程1
  • leetcode 128. 最长连续序列 - java
  • 【网络与爬虫 51】Scrapy-Cluster分布式爬虫集群:企业级大规模数据采集解决方案
  • 卷积神经网络学习
  • 新手小白使用jQuery在实际开发中常用到的经验
  • 讯飞晓医-讯飞医疗推出的个人AI健康助手
  • 初学python的我开始Leetcode题15-2
  • Web自动化技术选择
  • SpringBoot日志关系
  • 【能碳建设1】用AI+开源打造物联网+能碳管理+交易SaaS系统的最短路径实施指南
  • C#:dnSpy
  • 【密码学】7. 数字签名