目录
运动会进行中
难度:钻石
四: 占用内存:128 M时间限制:1.3秒
运动会快到了,小码哥班里组织彩排,小码哥作为体委不得不担当同学排队列的大任
为了让男女分配均匀,小码哥想知道队列中男女生人数一样的子序列(连续的)最多多长。
格式
输入格式:第一行一个正整数 n ,代表学生的人数,其中:n<100000;第二行 n 个用空格隔开的数,这些数只能是。或1,其中:。代表女生,1代表男生。
输出格式:输出一个非负整数,这个数表示在输入数据中最长的一段男女人数相等的子序列
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
const int N=1e5 + 7;
int n,a[N],sum[N],l[N*2],r[N*2],ans;
int main(){
cin >>n;
for(int i=1;i<=n;i++){
cin >>a[i];
if(a[i] == 0)//将女生用-1表示,更容易计算前缀和
a[i] = -1;
sum[i]=sum[i-1]+a[i];//前缀和后,寻找相同数字的最远距离
int tmp=sum[i]+n;//sum[i]的范围是-n到n,矫正下保证为正数
if (!l[tmp])
l[tmp] = i;
else
r[tmp]=i;
}
for (int i=0;i<2 * n;i++)
ans = max(ans,r[i] - l[i]);
cout <<ans <<endl;
return 0;
}
矩形
少难度:钻石·时间限制:1秒四占用内存:128 M
给定一个 N*M的矩阵,1表示已经占用了,0表示没有被占用,求一个由0构成的矩阵,使其周长最大。
格式
输入格式:第一行两个整数 n,m 含义如上;接下来 n 行每行 m 个数表示这个矩阵。
输出格式:输出一个数,表示最大周长。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> matrix(n, vector<int>(m));
// 读入矩阵
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
char ch;
cin >> ch;
matrix[i][j] = ch - '0';
}
}
int maxPerimeter = 0;
// 遍历所有可能的矩形
for (int x1 = 0; x1 < n; ++x1) {
for (int y1 = 0; y1 < m; ++y1) {
for (int x2 = x1; x2 < n; ++x2) {
for (int y2 = y1; y2 < m; ++y2) {
bool allZeros = true;
// 检查矩形内是否全部为0
for (int i = x1; i <= x2 && allZeros; ++i) {
for (int j = y1; j <= y2 && allZeros; ++j) {
if (matrix[i][j] != 0) {
allZeros = false;
}
}
}
if (allZeros) {
// 计算周长并更新最大周长
int perimeter = 2 * (x2 - x1 + 1) + 2 * (y2 - y1 + 1);
maxPerimeter = max(maxPerimeter, perimeter);
}
}
}
}
}
cout << maxPerimeter << endl;
return 0;
}
三连
少难度:钻石时间限制:1秒巴:占用内存:128 M
给出一个长度为n的序列,问有多少种方案将序列划分为恰好连续的三段(每个元素都属于某段),使得每一段的和都相等。
格式
输入格式:第一行:一个整数n;
第二行:n 个整数,表示序列。
输出格式:一个整数表示方案数。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> sequence(n);
long long totalSum = 0;
for (int i = 0; i < n; ++i) {
cin >> sequence[i];
totalSum += sequence[i];
}
// 如果总和不能被3整除,无法划分为三个和相等的段
if (totalSum % 3 != 0) {
cout << 0 << endl;
return 0;
}
long long targetSum = totalSum / 3;
long long prefixSum = 0, countTargetSum = 0, ways = 0;
for (int i = 0; i < n - 1; ++i) { // 注意,最后一个元素不参与划分
prefixSum += sequence[i];
if (prefixSum == 2 * targetSum) {
ways += countTargetSum;
}
if (prefixSum == targetSum) {
countTargetSum++;
}
}
cout << ways << endl;
return 0;
}
矩阵01变
黄金心 时间限制:1秒巴:占用内存:128 M难度:青
给定一个 N*M的矩阵,由0和1组成。现在请你求出,对于每个点(,y),以(1,1)为左上(2,y)为右下角的矩阵中包含多少个1。角,
例如:
800
810
000
的答案为:
000
0 1 1
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
char a[118][110];
int b[110][110],sum[110][110];
int m,n;
int main(){
scanf("%d%d",&m,&n);
for (int i = 1;i <= m;++i)
scanf("%s",a[i] + 1);
for (int i=1;i<=m;i++){
for (int j = 1;j<=n;j++) {
if (a[i][j] == '1')
b[i][j] = 1;
}
}
for (int i = 1;i<=m;i++){
for (int j=1;j<=n;j++) {
sum[i][j] =
sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + b[i][j];
}
}
for (int i =1;i<=m;i++) {
for (int j = 1; j <= n; j++) {
cout << sum[i][j] << " ";
}
cout << endl;
}
return 0;
}
最大异或和
乡 难度:黄金时间限制:2秒巴 占用内存:128 M
给定一串手链,每个珠子被赋予一个价值w;,现要从中截取连续的一段,使得他们的异或和最大(注意,手链还未串上)。
格式
输入格式:第 1行包含一个正整数 N
第 2 行n 个正整数 wi,表示珠子价格。
输出格式:一个正整数,输出最大异或和。
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
int n,a[2010],sum[2010],ans = -0x3f3f3f3f;
int main(){
cin >>n;
for (int i=1;i<=n;i++) {
cin >>a[i];
sum[i] = sum[i - 1] ^ a[i];
}
for (int i=1;i<=n;i++)
for (int j=1;j<=i;j++)
ans = max(ans,sum[i] ^ sum[j -1]);
cout << ans;
return 0;
}
切蛋糕
乡 难度:钻石时间限制:1秒四:占用内存:128 M
今天是小码哥的生日,家里人买了蛋糕。蛋糕由不同色彩分成了几个相同的部分,每一部分上面的水果都不同。由于小码哥对水果很有研究,他给每个水果都打了分。小码哥希望能吃到最多分数,但他又最多只能吃 m 块(m<n)。请你帮他从这n 小块中找出连续的最多 m 块蛋糕,使得其上的总分数最大。
格式
输入格式:第一行两个整数 n,m,意思如题目介绍:第二行 n 个整数,第 讠个整数代表第 讠部分的分数。
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
const int N=5e5 + 10;
int m,n,a[N],s[N],q[N],ans = -0x3f3f3f3f;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
int head = 0, tail = -1;
for (int i = 1; i <= n; i++) {
if (head <= tail && q[head] <= i - m)
head++;
while (head <= tail && s[i] <= s[q[tail]])
tail--;
q[++tail] = i;
ans = max(ans, s[i] - s[q[head]]);
}
cout << ans;
return 0;
}
信号灯
难度:钻石 时间限制:1秒巴: 占用内存:128 M
小码哥的农场有很多牛,这些牛很聪明,它们想和人一样过马路,于是小码哥给它们修建了马路。
但因为牛又不是那么聪明,他们有时会撞坏信号灯,小码哥很苦恼。
于是小码哥想请你帮忙算一下最少修好几个信号灯,可以有个编号连续的信号灯?
注:共有N个信号灯,编号为1~N,有B个信号灯损坏,给你它们的编号。
格式
输入格式:第一行输入三个正整数 N,K,B(1≤B,K≤N);接下来 B 行每行一个整数描述破损的灯的编号。
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
const int N=1e5 +10;
int n,k,b,a[N],sum [N],ans = 0x3f3f3f3f;
int main() {
cin >> n >> k >> b;
int tmp;
while (b--) {
cin >> tmp;
a[tmp] = 1;
}
for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i];
for (int i = 1; i + k - 1 <= n; i++)
ans = min(ans, sum[i + k - 1] - sum[i - 1]);
cout << ans;
return 0;
}
背军理
难度:黄金时间限制:1秒巴 占用内存:128 M
天哪天哪,军理有好多知识需要背呀。老师已经在厚厚的军理书上(该书一共有n页)画上了若干重点。我们现在已经知道,第i页有ai个重点。
现在小码哥向你询问了q次,每次询问给定一个闭区间,y,请你输出从第x页开始到第y页结束,这些页数之间一共有多少重点。
格式
输入格式:第一行一个整数n,表示书的总页数(书页码编号从第一页开始)接下来一行输入 n 个整数 a,表示该页上的老师画的重点个数;接下来一行一个整数 g,表示小码哥的询问次数;
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n,q,num[N],sum [N];
int main(){
cin >>n;
for (int i=1;i<=n;i++){
cin >>num[i];
sum[i] = sum[i - 1] + num[i];
}
cin >>q;
int x,y;
while(q--) {
cin >> x >> y;
cout << sum[y] - sum[x - 1] << endl;
}
return 0;
}
最大的平均值
难度:黄金时间限制:1秒四:占用内存:128 M
给一个数组,长度为几,找一个长度大于等于m 的子区间,使这个区间的元素的平均值最大。
格式
输入格式:第一行输入整数 n和 m,数据间用空格隔开,接下来 几 行,每行输入一个整数 ai。
输出格式:输出一个整数,表示平均值的最大值乘以 1000 再向下取整之后得到的结果。
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-6;
const int N = 1e5 + 10;
int n,m;
double a [N],sum [N],l,r;
int check(double mid){
double minn = 0;
for (int i=1;i<=n;i++)
sum[i] = sum[i-1] + a[i] - mid;
for(int i=m;i<=n;i++) {//假设第i个数是尾巴
minn = min(minn, sum[i - m]);
if (sum[i] > minn)
return 1;
}
return 0;
}
int main(){
cin >>n>>m;
for (int i=1;i<=n;i++) {
cin >> a[i];
r = max(r, a[i]);
}
while (r-l>=eps){
double mid = (l+r)/2;
if (check(mid))
l=mid;
else
r=mid;
}
cout <<(int)(r * 1000)<<endl;
return 0;
}
门票
乡难度:钻石时间限制:1秒巴:占用内存:128 M
小码哥家附近的一个主题公园最近搞了一个活动,小码哥在活动中获得了一等奖。而一等奖是一长串的纸条,上面有几个格子,每个格子里有一个数字,活动人员告诉小码哥,只要他裁下一段连续的格子,格子内数字的总和/裁下的格子的数量大于等于门票费t,那么小码哥就能用这段格子抵消门票费。
小码哥想要尽可能多的利用这个奖品,为此他想先知道有多少种裁剪的方案能裁出一段能抵消门票费的格子。
由于方案数可能很大所以需要你输出方案数对1e9+7取模的结果:
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 +7;
const int N = 1e6 + 10;
#define ll long long
ll n,t,a[N],sum[N],ans;
ll q[N];
void merge_sort(int l,int r,ll *a) {
if (l >= r)
return;
int mid = l + r >> 1;
merge_sort(l, mid, a), merge_sort(mid + 1, r, a);
int i = l, j = mid + 1, t = 0;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) {
q[t++] = a[j++];
ans += mid - i + 1;//降序排列,
//求非逆序数
ans %= MOD;
} else
q[t++] = a[i++];
}
while (i <= mid) q[t++] = a[i++];
while (j <= r) q[t++] = a[j++];
for (i = l, j = 0; i <= r; i++, j++)
a[i] = q[j];
}
int main(){
cin >>n >>t;
for(int i=1;i <= n;i++) {
cin >> a[i];
a[i] -= t;
sum[i] = sum[i - 1] + a[i];
}
merge_sort(0,n,sum);
cout <<ans % MOD;
return 0;
}
二阶前缀和
少 难度:黄金时间限制:1秒巴: 占用内存:128 M
在一个直角坐标系上,有 n个坐标上有元素值(其余坐标的元素值为0),现给定一些点的坐标(2i,y)和这个坐标的元素值 ",计算用一个边长为R的正矩形能囊括 坐标的元素值的和的最大值。不包括正方形的边界。
格式
输入格式:输入文件的第一行为两个正整数n和R;接下来的 n 行每行有3个自然数,分别表示 i,yi,vi。
输出格式:输出文件仅有一个正整数,表示一个正方形最多能囊括地图上的最大的元素值之
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
const int N =1010;
int a[N][N],s[N][N],ans;
using namespace std;
int main() {
int n, r;
cin >> n >> r;
while (n--) {
int x, y, w;
cin >> x >> y >> w;
x++, y++;
a[x][y] += w;
}
for (int i = 1; i <= 1001; i++) {
for (int j = 1; j <= 1001; j++) {
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
}
for (int i = r; i <= 1001; i++) {
for (int j = r; j <= 1001; j++) {
ans =
max(ans, s[i][j] - s[i - r][j] - s[i][j - r] + s[i - r][j - r]);
}
}
cout << ans;
return 0;
}
距离平方和
难度:黄金时间限制:1秒巴:占用内存:128 M
你有几个点,请编写一个程序,求这n个点的距离的平方和。
格式
输入格式:第一行:-个整数n(0<n≤ 100000)接下来n 行:每行两个整数 x,y,表示该点坐标 (-10000 <x,y≤10000)
输出格式:仅一行:所有点的距离的平方和。
//
// Created by abner on 2024/3/6.
//
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll ans,sx,sy,n;
int main() {
cin >> n;
for (int i = 0; i < n; ++i) {
int x, y;
cin >> x >> y;
ans += (n - 1) * (x * x + y * y) - ((x * sx + y * sy) * 2);
sx += x, sy += y;
}
cout << ans;
return 0;
}