洛谷-算法2-2-常见优化技巧1

P1102 A-B 数对

题目背景

出题是一件痛苦的事情!

相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!

题目描述

给出一串正整数数列以及一个正整数 C,要求计算出所有满足 A−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。

输入格式

输入共两行。

第一行,两个正整数 N,C。

第二行,第 i 个数为 ai​,数字之间用一个空格隔开,共 N 个正整数,作为要求处理的那串数。

输出格式

一行,表示该串正整数中包含的满足 A−B=C 的数对的个数。

输入输出样例

输入 #1复制

复制代码
4 1
1 1 2 3

输出 #1复制

复制代码
3

说明/提示

对于 75% 的数据,1≤N≤2000。

对于 100% 的数据,1≤N≤2×105,0≤ai​<230,1≤C<230。

2017/4/29 新添数据两组

实现代码:

cpp 复制代码
    #include <iostream>
    #include <map>
    using namespace std;
    typedef long long LL;
    LL a[200001];
    map<LL,LL> m;
    int main() {
        int n;
        LL c;
        LL ans=0;
        cin >> n >> c;
        for(int i=1;i<=n;i++) {
            cin >> a[i];
            m[a[i]]++;
            a[i]-=c;    
        } 
        for(int i=1;i<=n;i++) ans+=m[a[i]];
        cout << ans << endl;
        return 0;
}

P1638 逛画展

题目描述

博览馆正在展出由世上最佳的 m 位画家所画的图画。

游客在购买门票时必须说明两个数字,x 和 y,代表他要看展览中的第 x 幅至第 y 幅画(包含 x,y)之间的所有图画,而门票的价钱就是一张图画一元。

Sept 希望入场后可以看到所有名师的图画。当然,他想最小化购买门票的价格。

请求出他购买门票时应选择的 x,y,数据保证一定有解。

若存在多组解,输出 x 最小的那组

输入格式

第一行两个整数 n,m,分别表示博览馆内的图画总数及这些图画是由多少位名师所绘画的。

第二行包含 n 个整数 ai​,代表画第 i 幅画的名师的编号。

输出格式

一行两个整数 x,y。

输入输出样例

输入 #1复制

复制代码
12 5
2 5 3 1 3 2 4 1 1 5 4 3

输出 #1复制

复制代码
2 7

说明/提示

数据规模与约定
  • 对于 30% 的数据,有 n≤200,m≤20。
  • 对于 60% 的数据,有 n≤105,m≤103。
  • 对于 100% 的数据,有 1≤n≤106,1≤ai≤m≤2×103。

实现代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000005],b[2005],k,ans,l,r,ll,rr;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	l=1; r=1; k=1; b[a[1]]=1; ans=1000005;
	while(l<=r && r<=n)
	{
		if(k==m)
		{
			if(ans>r-l+1)	
			{
				ans=r-l+1;
				ll=l; rr=r;
			}
			b[a[l]]--;
			if(b[a[l]]==0) k--;
			l++;
		}
		else{
			r++;
			b[a[r]]++;
			if(b[a[r]]==1) k++;
		}
	}
	printf("%d %d",ll,rr);
	return 0;
}

P1115 最大子段和

题目描述

给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。

输入格式

第一行是一个整数,表示序列的长度 n。

第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai​。

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1复制

复制代码
7
2 -4 3 -1 2 -4 3

输出 #1复制

复制代码
4

说明/提示

样例 1 解释

选取 [3,5] 子段 {3,−1,2},其和为 4。

数据规模与约定
  • 对于 40% 的数据,保证 n≤2×103。
  • 对于 100% 的数据,保证 1≤n≤2×105,−104≤ai≤104。

2026/01/21:增加一组 hack 数据

实现代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,a[200020],b[200020],i,ans=-2147483647;

int main(){
   cin>>n;
   for(i=1;i<=n;i++){
       cin>>a[i];
       if(i==1) b[i]=a[i];
       else b[i]=max(a[i],b[i-1]+a[i]);
       ans=max(ans,b[i]);
   }
   cout<<ans;
   return 0;
}

P7072 [CSP-J 2020] 直播获奖

题目描述

NOI2130 即将举行。为了增加观赏性,CCF 决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞赛的获奖率为 w%,即当前排名前 w% 的选手的最低成绩就是即时的分数线。

更具体地,若当前已评出了 p 个选手的成绩,则当前计划获奖人数为 max(1,⌊p×w%⌋),其中 w 是获奖百分比,⌊x⌋ 表示对 x 向下取整,max(x,y) 表示 x 和 y 中较大的数。如有选手成绩相同,则所有成绩并列的选手都能获奖,因此实际获奖人数可能比计划中多。

作为评测组的技术人员,请你帮 CCF 写一个直播程序。

输入格式

第一行有两个整数 n,w。分别代表选手总数与获奖率。

第二行有 n 个整数,依次代表逐一评出的选手成绩。

输出格式

只有一行,包含 n 个非负整数,依次代表选手成绩逐一评出后,即时的获奖分数线。相邻两个整数间用一个空格分隔。

输入输出样例

输入 #1复制

复制代码
10 60
200 300 400 500 600 600 0 300 200 100

输出 #1复制

复制代码
200 300 400 400 400 500 400 400 300 300

输入 #2复制

复制代码
10 30
100 100 600 100 100 100 100 100 100 100

输出 #2复制

复制代码
100 100 600 600 600 600 100 100 100 100

说明/提示

样例 1 解释


数据规模与约定

各测试点的 n 如下表:

测试点编号 n=
1∼3 10
4∼6 500
7∼10 2000
11∼17 104
18∼20 105

对于所有测试点,每个选手的成绩均为不超过 600 的非负整数,获奖百分比 w 是一个正整数且 1≤w≤99。


提示

在计算计划获奖人数时,如用浮点类型的变量(如 C/C++ 中的 floatdouble,Pascal 中的 realdoubleextended 等)存储获奖比例 w%,则计算 5×60% 时的结果可能为 3.000001,也可能为 2.999999,向下取整后的结果不确定。因此,建议仅使用整型变量,以计算出准确值。

附件下载

live3.in74.50KB

live3.ans78.13KB

实现代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

priority_queue<int> ma_hp;
priority_queue<int, vector<int>, greater<int> > mi_hp;

int n, w, now, num;

void qwq()
{
	if (mi_hp.size()<now)
	{
		mi_hp.push(ma_hp.top());
		ma_hp.pop();
	} 
	if (mi_hp.size() > now)
	{
		ma_hp.push(mi_hp.top());
		mi_hp.pop();
	}
	
} 

void push(int num)
{
	if (num >= ma_hp.top()) mi_hp.push(num);
		else ma_hp.push(num);
	qwq();
}

int main()
{
	scanf("%d%d", &n, &w);
	ma_hp.push(0);
	for (int p = 1; p <= n; p++)
	{
		now=max(1,p*w/100); 
		scanf("%d", &num);
		push(num);
		printf("%d ", mi_hp.top()); 
	}
	return 0;
}

P2671 [NOIP 2015 普及组] 求和

题目背景

NOIP2015 普及组 T3

题目描述

一条狭长的纸带被均匀划分出了 n 个格子,格子编号从 1 到 n。每个格子上都染了一种颜色 colori​(用 [1,m] 当中的一个整数表示),并且写了一个数字 numberi​。

编号 1 2 3 4 5 6
颜色和数字 5 5 3 2 2 2

定义一种特殊的三元组:(x,y,z),其中 x,y,z 都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:

  1. x,y,z 都是整数,x<y<z,y−x=z−y。

  2. colorx​=colorz​。

满足上述条件的三元组的分数规定为 (x+z)×(numberx​+numberz​)。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以 10007 所得的余数即可。

输入格式

第一行是用一个空格隔开的两个正整数 n 和 m,n 表示纸带上格子的个数,m 表示纸带上颜色的种类数。

第二行有 n 用空格隔开的正整数,第 i 个数字表示纸带上编号为 i 格子上面写的数字 numberi​。

第三行有 n 用空格隔开的正整数,第 i 数字表示纸带上编号为 i 格子染的颜色 colori​。

输出格式

一个整数,表示所求的纸带分数除以 10007 所得的余数。

输入输出样例

输入 #1复制

复制代码
6 2
5 5 3 2 2 2
2 2 1 1 2 1

输出 #1复制

复制代码
82

输入 #2复制

复制代码
15 4
5 10 8 2 2 2 9 9 7 7 5 6 4 2 4
2 2 3 3 4 3 3 2 4 4 4 4 1 1 1

输出 #2复制

复制代码
1388

说明/提示

样例 1 解释

纸带如题目描述中的图所示。

所有满足条件的三元组为:(1,3,5),(4,5,6)。

所以纸带的分数为 (1+5)×(5+2)+(4+6)×(2+2)=42+40=82。

对于第 1 组至第 2 组数据, 1≤n≤100,1≤m≤5;

对于第 3 组至第 4 组数据,1≤n≤3000,1≤m≤100;

对于第 5 组至第 6 组数据,1≤n≤105,1≤m≤105,且不存在出现次数超过 20 的颜色;

对于全部 10 组数据,1≤n≤105,1≤m≤105,1≤colori​≤m,1≤numberi​≤105。

实现代码:

cpp 复制代码
#include <cstdio>

const int N = 100000;
const int M = 10007;
int n, m;
int sum[N + 1][2], nt[N + 1][2];
int color[N + 1], number[N + 1];
long long ans = 0;

int main()
{
    scanf(" %d %d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &number[i]);
        number[i] %= M;
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d", &color[i]);
        int c = color[i];
        int g = i % 2;
        nt[c][g]++;
        sum[c][g] += number[i];
        sum[c][g] %= M;
    }
    for(int i = 1; i <= n; i++) {
        int c = color[i];
        int g = i % 2;
        ans += i % M * ((sum[c][g] + (nt[c][g] - 2) % M * number[i] + M) % M);
        ans %= M;
    }
    printf("%lld", ans);
    return 0;
}
相关推荐
酉鬼女又兒1 小时前
JavaLeetCode 第一题「两数之和」:从暴力枚举到一遍哈希表的正确与错误实现,详解HashMap核心知识点及常见陷阱
java·开发语言·数据结构·算法·leetcode·职场和发展·散列表
黎阳之光2 小时前
视频孪生重构轨交数字孪生新范式|黎阳之光以自主核心技术破解落地难题
大数据·人工智能·算法·安全·数字孪生
云淡风轻~窗明几净2 小时前
关于TSP的sealine算法与角谷猜想(2026-04-25)
数据结构·人工智能·算法·动态规划·模拟退火算法
wayz112 小时前
Day 13:朴素贝叶斯分类器
人工智能·算法·机器学习·朴素贝叶斯
白夜11172 小时前
C++(mixins 混入模式)
开发语言·c++·笔记
前端摸鱼匠2 小时前
【AI大模型春招面试题29】对比学习(Contrastive Learning)在大模型预训练中的应用?
人工智能·学习·算法·面试·大模型·求职招聘
探物 AI2 小时前
【感知·单目测距】单目摄像头测距原理与前向碰撞预警(FCWS)实现
算法·目标检测·计算机视觉
gloomyfish2 小时前
【洞察微瑕】YOLO11+QWEN-VL实现墙体裂缝检测与文字报告生成
人工智能·opencv·算法·计算机视觉
无风听海2 小时前
Python 哨兵值模式(Sentinel Value Pattern)深度解析
开发语言·python·sentinel