noip2015普及组题解最终

合集下载

NOIP2015初赛普及组C++题目及答案 (2)

NOIP2015初赛普及组C++题目及答案 (2)

选手注意:第二十一届全国青少年信息学奥林匹克联赛初赛普及组C++语言试题竞赛时间:2015年10月11日14:3016:30试题纸共有7页,答题纸共有2页,满分100分。

请在答题纸上作答,写在试题纸上的一律无效。

不得使用任何电子设备(如计算器、手机、电子词典等)或查阅任何书籍资料。

一、单项选择题(共20题,每题分,共计30分;每题有且仅有一个正确选项)1. 1MB等于()。

字节字节字节字节2. 在PC机中,PENTIUM (奔腾)、酷睿、赛扬等是指()。

A.生产厂家名称B.硬盘的型号的型号 D.显示器的型号3. 操作系统的作用是()。

A.把源程序译成目标程序B.便于进行数据管理C. 控制和管理系统资源D.实现硬件之间的连接4. 在计算机内部用来传送、存贮、加工处理的数据或指令都是以()形式进行的。

A.二进制码B.八进制码C.十进制码D.智能拼音码5. 下列说法正确的是()。

A. CPU的主要任务是执行数据运算和程序控制B. 存储器具有记忆能力,其中信息任何时候都不会丢失C. 两个显示器屏幕尺寸相同,则它们的分辨率必定相同D. 个人用户只能使用Wifi的方式连接到Internet6. 二进制数00100100和00010100的和是()。

A. 00101000 010000017. 与二进制小数相等的十六进制数是()A. 0.8 0.4 所谓的“中断”是指()。

A. 操作系统随意停止一个程序的运行B. 当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的过程C. 因停机而停止一个程序的运行D. 电脑死机9. 计算机病毐是()。

A. 通过计算机传播的危害人体健康的一种病毒B. 人为制造的能够侵入计算机系统并给计算机带来故障的程序或指令集合C. 一种由于计算机元器件老化而产生的对生态环境有害的物质D. 利用计算机的海量高速运算能力而研制出来的用于疾病预防的新型病毒可以用于()。

A.远程传输文件B.发送电子邮件C.浏览网页D.网上聊天11.下面哪种软件不属于即时通信软件()。

noip2015初赛普及组答案分析

noip2015初赛普及组答案分析

单项选择题1.A。

计算机内部的用来传送、存贮、加工处理的数据或指令都是以二进制形式进行的。

2.A。

写这题我用的是排除法,B选项显然不对,内存在断电后数据会丢失,C选项也是,屏幕的分辨率是可以手动调整的,D选项,当年我们都用宽带连接Internet的。

3.A。

二进制小数转化为十六进制小数时,每四位二进制数转化为以为十六进制数,故0.10002可以转化为0.816。

4.D。

我的做法是将每个数都化为二进制形式,因为十六进制数和八进制数转化为二进制数很容易,最后求得答案是D。

5.D。

在链表中,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域,结点与结点之间是用指针连接的,故地址不必连续。

6.B。

模拟一下进栈出栈的过程就行了,共有6次操作:进栈,进栈,出栈,进栈,进栈,出栈,每次操作后栈内元素分别为”a”,”ab”,”a”,”a b c”,”a b c d”,”a b c”,故最后栈顶元素是c。

7.B。

前序遍历的顺序是”根->左->右”,后序遍历的顺序是”左->右->根”,对照四个答案,只有B能满足题目要求。

8.B。

我们知道树高为n的满二叉树的结点个数为2n−1,当树高为5时结点个数为31,当树高为6时结点个数为63,故答案是B。

9.B。

画一张图的事情,就不说了。

10.D。

由递推公式可得T(n)=1+(1+2+…+n)=n2+n2+1,故算法时间的复杂度为O(n2)。

11.D。

用vector存边,由一个顶点的边引到另一个顶点,再不断引出别的顶点,过程中每个顶点和每条边都只用到一遍,故复杂度为O(n+e)。

12.A。

哈夫曼算法用来求哈夫曼树,此树的特点就是引出的路程最短,求的过程运用到贪心思想,具体的请参考一下别的文章。

13.D。

llink和rlink分别指向前驱和后继,不妨设p的前驱为o,在未插入前p->llink就是o,o->rlink就是p,插入时,先将o->rlink赋为q,再将q->rlink赋为p,然后将q->llink赋为o,最后将p->llink赋为q。

NOIP普及组复赛解题报告

NOIP普及组复赛解题报告

N O I P2015普及组解题报告南京师范大学附属中学树人学校CT1. 金币c/pas)【问题描述】国王将金币作为工资,发放给忠诚的骑士。

第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。

请计算在前K天里,骑士一共获得了多少金币。

【输入格式】输入文件名为。

输入文件只有1行,包含一个正整数K,表示发放金币的天数。

【输出格式】输出文件名为。

输出文件只有1行,包含一个正整数,即骑士收到的金币数。

【数据说明】对于100%的数据,1 ≤K ≤10,000。

【思路】模拟【时空复杂度】O(k),O(1)2、扫雷游戏(c/pas)【问题描述】扫雷游戏是一款十分经典的单机小游戏。

在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。

玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。

游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。

现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。

注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

【输入格式】输入文件名为。

输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。

接下来n行,每行m个字符,描述了雷区中的地雷分布情况。

字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。

相邻字符之间无分隔符。

【输出格式】输出文件名为。

输出文件包含n行,每行m个字符,描述整个雷区。

用’*’表示地雷格,用周围的地雷个数表示非地雷格。

相邻字符之间无分隔符。

【数据说明】对于100%的数据,1≤n≤100,1≤m≤100。

noip2015普及组复赛试题

noip2015普及组复赛试题

noip2015普及组复赛试题题目一:矩阵运算给定一个n阶方阵A(1 ≤ n ≤ 100),求A的所有指定行指定列删除后得到的新矩阵的行列式。

输入格式:输入第一行包含一个整数n,表示方阵的阶数。

接下来n行,每行包含n个整数,表示方阵A的元素。

接下来一行包含两个整数,表示要删除的行和列的序号。

输出格式:输出一个整数,表示新矩阵的行列式的值。

题目要求:首先,我们需要编写一个能够计算矩阵行列式的函数,然后根据题意进行修改,使其能够处理删除指定行列后的新矩阵,并返回新矩阵的行列式的值。

算法思路:我们可以使用拉普拉斯展开定理来计算矩阵行列式的值。

首先定义一个变量result,初始化为0。

然后遍历矩阵的第一行元素,对于第i 个元素,根据其正负性,计算其余元素组成的(n-1)阶子矩阵的行列式的值,并递归调用自身。

最后将每个元素计算得到的行列式值乘以其对应的元素,累加到result上。

然后根据题目要求,在计算每个元素对应的子矩阵时,判断是否需要删除指定的行列。

如果需要删除,则直接跳过该行列,否则继续计算。

代码如下:```pythondef determinant(matrix):n = len(matrix)if n == 1:return matrix[0][0]result = 0for i in range(n):if n > 2:sub_matrix = [row[:i] + row[i+1:] for row in matrix[1:]]else:sub_matrix = matrix[1:]det = determinant(sub_matrix)result += (-1) ** i * matrix[0][i] * detreturn resultn = int(input())matrix = []for _ in range(n):row = list(map(int, input().split()))matrix.append(row)row, col = map(int, input().split())matrix = [matrix[i][:col] + matrix[i][col+1:] for i in range(row)] # 删除指定列matrix = matrix[:row] + matrix[row+1:] # 删除指定行result = determinant(matrix)print(result)```题目二:水果分配小明和他的朋友们买了n个水果,其中有x个苹果和y个香蕉。

NOIP2015复赛普及组试题

NOIP2015复赛普及组试题

CCF 全国信息学奥林匹克联赛(NOIP2015)复赛
普及组
(请选手务必仔细阅读本页内容)
一.题目概况
二.提交源程序文件名
三.编译命令(不包含任何优化开关)
注意事项:
1、文件名(程序名和输入输出文件名)必须使用英文小写。

2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。

3、全国统一评测时采用的机器配置为:CPU AMD Athlon(tm) II x2 240 processor,2.8GHz,
内存4G,上述时限以此配置为准。

4、只提供Linux 格式附加样例文件。

5、特别提醒:评测在当前最新公布的NOI Linux 下进行,各语言的编译器版本以其为准。

1. 金币
(coin.cpp/c/pas)
国王将金币作为工资,发放给忠诚的骑士。

第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N 天每天收到N 枚金币后,骑士会在之后的连续N+1 天里,每天收到N+1 枚金币。

请计算在前K 天里,骑士一共获得了多少金币。

【输入格式】
输入文件名为coin.in。

输入文件只有1 行,包含一个正整数K,表示发放金币的天数。

【输出格式】
输出文件名为coin.out。

输出文件只有1 行,包含一个正整数,即骑士收到的金币数。

【输入输出样例1】。

2015年NOIP信息学奥林匹克初赛试题和答案(普及组C++语言)

2015年NOIP信息学奥林匹克初赛试题和答案(普及组C++语言)

第二十一届全国青少年信息学奥林匹克联赛初赛普及组C++语言试题竞赛时间:2015 年10 月11 日14:30-16:30一、单项选择题(共20 题,每题1.5 分,共计30 分;每题有且仅有一个正确选项)⒈1MB 等于( )。

A.10000 字节B.1024 字节C.1000×1000 字节D.1024×1024 字节⒉在PC 机中,PENTIUM(奔腾)、酷睿、赛扬等是指()。

A.生产厂家名称 B.硬盘的型号 C.CPU 的型号 D.显示器的型号⒊操作系统的作用是()。

A.把源程序译成目标程序B.便于进行数据管理C.控制和管理系统资源D.实现硬件之间的连接⒋在计算机内部用来传送、存贮、加工处理的数据或指令都是以()形式进行的。

A.二进制码B.八进制码C.十进制码D.智能拼音码⒌下列说法正确的是()。

A.CPU 的主要任务是执行数据运算和程序控制B.存储器具有记忆能力,其中信息任何时候都不会丢失C.两个显示器屏幕尺寸相同,则它们的分辨率必定相同D.个人用户只能使用Wifi 的方式连接到Internet⒍二进制数00100100 和00010100 的和是( )。

A.00101000B.01100111C.01000100D.00111000⒎与二进制小数0.1 相等的十六进制数是()。

A.0.8B.0.4C.0.2D.0.1⒏所谓的“中断”是指()。

A.操作系统随意停止一个程序的运行B.当出现需要时,CPU 暂时停止当前程序的执行转而执行处理新情况的过程C.因停机而停止一个程序的运行D.电脑死机⒐计算机病毒是()。

A.通过计算机传播的危害人体健康的一种病毒B.人为制造的能够侵入计算机系统并给计算机带来故障的程序或指令集合C.一种由于计算机元器件老化而产生的对生态环境有害的物质D.利用计算机的海量高速运算能力而研制出来的用于疾病预防的新型病毒⒑FTP 可以用于( )。

A.远程传输文件B.发送电子邮件C.浏览网页D.网上聊天⒒下面哪种软件不属于即时通信软件()。

NOIP2015复赛普及组试题

NOIP2015复赛普及组试题

CCF 全国信息学奥林匹克联赛(NOIP2015)复赛普及组(请选手务必仔细阅读本页内容)一.题目概况二.提交源程序文件名三.编译命令(不包含任何优化开关)【问题描述】注意事项:1、文件名(程序名和输入输出文件名)必须使用英文小写。

2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。

3、全国统一评测时采用的机器配置为:CPU AMD Athlon(tm) II x2 240 processor,2.8GHz,内存4G,上述时限以此配置为准。

4、只提供Linux 格式附加样例文件。

5、特别提醒:评测在当前最新公布的NOI Linux 下进行,各语言的编译器版本以其为准。

1. 金币(coin.cpp/c/pas)国王将金币作为工资,发放给忠诚的骑士。

第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N 天每天收到N 枚金币后,骑士会在之后的连续N+1 天里,每天收到N+1 枚金币。

请计算在前K 天里,骑士一共获得了多少金币。

【输入格式】输入文件名为coin.in。

输入文件只有1 行,包含一个正整数K,表示发放金币的天数。

【输出格式】输出文件名为coin.out。

【问题描述】输出文件只有1 行,包含一个正整数,即骑士收到的金币数。

【输入输出样例1】【输入输出样例1 说明】骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。

因此一共收到1+2+2+3+3+3=14 枚金币。

【输入输出样例2】【数据说明】对于100%的数据,1 ≤ K ≤ 10,000。

2.扫雷游戏(mine.cpp/c/pas)扫雷游戏是一款十分经典的单机小游戏。

在n 行m 列的雷区中有一些格子含有地雷【问题描述】(称之为地雷格),其他格子不含地雷(称之为非地雷格)。

全国青少年信息学奥林匹克联赛c++普及组 2015年复赛试题讲解

全国青少年信息学奥林匹克联赛c++普及组 2015年复赛试题讲解

{
if(d[i+l1][j+l2]!=-1)
d[i+l1][j+l2]++;
}//边上八个位置的格子不是雷则
数值加1
}
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
if(
d[i][j]==-1) cout<<'*';
else cout<<d[i][j];
cout<<endl;
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
int const maxn=100005;
struct data
{

int x,s,a;//序号,距离,疲劳值
};
data dt[maxn];
int n,ans[maxn],lt,rt,now;
bool cmp(data d1, data d2)
{

return d1.a<d2.a;
}
int main()
{

scanf("%d",&n);

for(int i=1;i<=n;i++)

scanf("%d",&dt[i].s);
位置大于最远距离远的点的依次搜索找到最大值 (距离两倍+疲劳值),与最大堆的堆顶比较。

noip2015普及组初赛试题

noip2015普及组初赛试题

noip2015普及组初赛试题题目:NOIP2015普及组初赛试题解析一、选择题1. 算法基础与复杂度分析本题考查了对算法复杂度的理解,要求参赛者能够区分不同算法的时间复杂度,并能够根据输入数据的大小估计算法的执行时间。

解答此题需要掌握大O表示法,并能够对常见的算法复杂度进行比较和分析。

2. 数据结构的应用此题要求参赛者对数组、链表等基本数据结构有深入的了解,并能够灵活运用到实际问题中。

同时,还需要理解不同数据结构之间的转换,以及它们在内存中的存储方式。

3. 递归思想递归是解决复杂问题的有力工具,本题通过一系列递归相关问题,考察参赛者对递归思想的掌握程度。

解答此类题目需要理解递归的基本概念,以及如何通过递归解决实际问题。

二、问题求解1. 数组与字符串本部分题目主要涉及数组和字符串的处理。

参赛者需要掌握数组的遍历、查找、排序等基本操作,以及字符串的拼接、查找、替换等操作。

此外,还需要了解如何在这些操作中优化算法,提高效率。

2. 数论与组合数学数论和组合数学是计算机科学中的重要分支,本部分题目要求参赛者具备一定的数学基础,能够运用数论和组合数学的知识解决问题。

解答此类题目需要掌握质数、因数分解、最大公约数、最小公倍数等数论知识,以及排列组合、二项式定理等组合数学知识。

3. 图论基础图论是计算机科学中的另一重要分支,本部分题目主要考察图的基本概念和算法。

参赛者需要理解图的表示方法,如邻接矩阵和邻接表,以及图的遍历算法,如深度优先搜索和广度优先搜索。

此外,还需要了解一些基本的图论问题,如最小生成树、最短路径等。

三、编程实践1. 代码实现本部分题目要求参赛者将前面的问题求解转化为具体的代码实现。

这不仅考察编程语言的使用能力,还考察算法实现的准确性和效率。

参赛者需要熟练掌握至少一种编程语言,如C/C++、Java或Python,并能够编写清晰、高效的代码。

2. 调试与优化编程实践中不可避免地会遇到代码错误和性能瓶颈。

NOIP2015普及组复赛试题解题报告word版第一二题满分程序

NOIP2015普及组复赛试题解题报告word版第一二题满分程序

NOIP2015普及组复赛试题解题报告word版第一二题满分程序CCF全国信息学奥林匹克联赛(NOIP2015)复赛普及组一.题目概况中文题目名称金币扫雷游戏求和推销员英文题目与子目录名coin mine sum salesman 可执行文件名coin mine sum salesman 输入文件名coin.in mine.in sum.in salesman.in 输出文件名coin.out mine.out sum.out salesman.out 每个测试点时限1秒1秒1秒1秒测试点数目10101010每个测试点分值10101010附加样例文件有有有有结果比较方式全文比较(过滤行末空格及文末回车)题目类型传统传统传统传统运行内存上限128M128M128M128M二.提交源程序文件名对于C++语言coin.cpp mine.cpp sum.cpp salesman.cpp 对于C语言coin.c mine.c sum.c salesman.c 对于pascal语言coin.pas mine.pas sum.pas salesman.pas三.编译命令(不包含任何优化开关)对于C++语言g++-o coincoin.cpp-lm g++-o minemine.cpp-lmg++-o sumsum.cpp-lmg++-o salesmansalesman.cpp-lm对于C语言gcc-o coin coin.c-lm gcc-o mine mine.c-lmgcc-o sumsum.c-lmgcc-o salesmansalesman.c-lm对于pascal语言fpc coin.pas fpc mine.pas fpc sum.pas fpc salesman.pas注意事项:1、文件名(程序名和输入输出文件名)必须使用英文小写。

2、C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。

NOIP2015普及组复赛试题讲解(c版本)

NOIP2015普及组复赛试题讲解(c版本)
➢ 每组的数的下标用a1~an表示,数值用n1~nk表 示,用sum表示数值之和。答案就是 (n1+n2)*(a1+a2)+……+……。如果这样做就是 O(n^2/m)的算法。(估计能过60分)
➢ 转换公式(a1*n1+a2*n2+…+ak*nk)*(n-2)+
(a1+a2+…+ak)*(n1+n2+…nk) O(n)的时间复杂度

cin>>number[i];

for( i=1;i<=n;i++)

cin>>color[i];

for(y=1;y<=n;y++)

{

int j=1;

while(y-
j>=1&&y+j<=n)

{

if(color[y-j]==color[y+j])

sum+=2*y*(number[y-
➢ int n,ans[maxn],lt,rt,now;
➢ bool cmp(data d1, data d2)
➢{

return d1.a<d2.a;
➢}
➢ int main()
➢{

scanf("%d",&n);

for(int i=1;i<=n;i++)

scanf("%d",&dt[i].s);
➢ int ans=0;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本次试题前2题比较简单,34题容易拿到部分分,但满分有难度1. 金币(coin.cpp/c/pas)【问题描述】国王将金币作为工资,发放给忠诚的骑士。

第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。

请计算在前K天里,骑士一共获得了多少金币。

【输入格式】输入文件名为coin.in。

输入文件只有1行,包含一个正整数K,表示发放金币的天数。

【输出格式】输出文件名为coin.out。

输出文件只有1行,包含一个正整数,即骑士收到的金币数。

【样例输入】coin.in6【样例输出】coin.out14【输入输出样例1说明】骑士第一天收到一枚金币;第二天和第三天,每天收到两枚金币;第四、五、六天,每天收到三枚金币。

因此一共收到1+2+2+3+3+3=14枚金币。

【数据范围】对于100%的数据,1 ≤K ≤10,000。

【题解】关注到K的范围是10000后,就不需要考虑数学公式,纯模拟就行,考点就是for循环了var i,j,count,n,ans:longint;beginassign(input,'coin.in');reset(input);assign(output,'coin.out');rewrite(output);readln(n);for i:=1 to 1000 dofor j:=1 to i dobegininc(count);inc(ans,i);if count=n then beginwriteln(ans);close(input);close(output);halt;end;end;end.2.扫雷游戏(mine.cpp/c/pas)【问题描述】扫雷游戏是一款十分经典的单机小游戏。

在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。

玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。

游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。

现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。

注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

【输入格式】输入文件名为mine.in。

输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。

接下来n行,每行m个字符,描述了雷区中的地雷分布情况。

字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。

相邻字符之间无分隔符。

【输出格式】输出文件名为mine.out。

输出文件包含n行,每行m个字符,描述整个雷区。

用’*’表示地雷格,用周围的地雷个数表示非地雷格。

相邻字符之间无分隔符。

【样例输入】3 3*??????*?【样例输出】*102211*1【数据说明】对于100%的数据,1≤n≤100,1≤m≤100。

【题解】行列数最多100,也就是100*100的单元格数量,一个个判断过去也就100*100*8个方向,判断边界时注意数组的下标别越界就行了。

考点还是for循环哦,可以考虑使用增量数组,不过就8个方向手写也很快的。

varn,m,i,j,count:longint;a:array[0..101,0..101] of char;beginassign(input,'mine.in');reset(input);assign(output,'mine.out');rewrite(output);readln(n,m);for i:=1 to n do beginfor j:=1 to m doread(a[i,j]);readln;end;for i:=1 to n do beginfor j:=1 to m doif a[i,j]='*' then write(a[i,j])else begincount:=0;if a[i-1,j-1]='*' then inc(count);if a[i-1,j]='*' then inc(count);if a[i-1,j+1]='*' then inc(count);if a[i,j-1]='*' then inc(count);if a[i,j+1]='*' then inc(count);if a[i+1,j-1]='*' then inc(count);if a[i+1,j]='*' then inc(count);if a[i+1,j+1]='*' then inc(count);write(count);end;writeln;end;close(input);close(output);end.3. 求和(sum.cpp/c/pas)【问题描述】一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。

每个格子上都染了一种颜色color i(用[1,m]当中的一个整数表示),并且写了一个数字number i。

定义一种特殊的三元组:(x, y, z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:1. x,y,z都是整数,x<y<z,y−x= z−y2. color x=color z满足上述条件的三元组的分数规定为(x+z)∗(number x+number z)。

整个纸带的分数规定为所有满足条件的三元组的分数的和。

这个分数可能会很大,你只要输出整个纸带的分数除以10,007所得的余数即可。

【输入格式】输入文件名为sum.in。

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

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

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

【输出格式】输出文件名为sum.out。

共一行,一个整数,表示所求的纸带分数除以10,007所得的余数。

【样例输入】6 25 5 3 2 2 22 2 1 1 2 1【样例输出】82【输入输出样例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≤100000,1≤m≤100000,且不存在出现次数超过20的颜色;对于全部10组数据,1≤n≤100000,1≤m≤100000,1≤color i≤m,1≤number i≤100000。

【题解】可以理解为n个元素每个元素有三个属性分别是数值Number、颜色和编号,对于任意两个满足2个条件的元素进行相应的统计,第1个条件其实等价于这两个元素的编号都是奇数或都是偶数,第2个条件是相同颜色值。

观察数据范围我们可以发现前4组数据的n只有3000,O(N^2)的算法就能拿分,直接穷举任意两个元素,这个代码非常简短的:var //预期得 40分的程序n,m,i,j:longint;a,b:array[0..100000] of qword;ans:qword;beginassign(input,'sum.in');reset(input);assign(output,'sum.out');rewrite(output);readln(n,m);for i:=1 to n do read(a[i]);readln;for i:=1 to n do read(b[i]);readln;for i:=1 to n dofor j:=i+1 to n doif not odd(i+j) and (b[i]=b[j]) then beginans:=(ans+(a[i]+a[j])*(i+j)) mod 10007;end;writeln(ans);close(input);close(output);end.如何避免超时呢?介绍两种满分的方法【第一种方法】从给出公式入手:(假设编号为x1,x2,x3,x4,x5的元素彼此间都符合题目要求的2个条件,其实就是它们的奇偶性相同、颜色相同)(x1+x2)∗(number x1+number x2)(x1+x3)∗(number x1+number x3)(x1+x4)∗(number x1+number x4)(x1+x5)∗(number x1+number x5)(x2+x3)∗(number x2+number x3)(x2+x4)*(nu mber x2+number x4)(x2+x5)*(nu mber x2+number x5)(x3+x4)*(nu mber x3+number x4)(x3+x5)*(nu mber x3+number x5)(x4+x5)*(nu mber x4+number x5)(1)把它们展开来就能发现xi*number x i的数量都就是5-1=4个,如果这样的元素有N 个,则有N-1个xi*number x i(2)然后是x1(number x2+number x3+number x4 +number x5)+ x2(number x3+number x4+number x5)+ x3 (number x4+number x5)+ x4 *number x5(3)类似的number x1(x2+x3+x4+x5)+ number x2(x3+x4+x5)+ number x3(x4+x5)+ number x4*x5 (2)和(3)我们可以归为一类(考虑有n个符合条件的元素)(2)的推广式是Xi(number xi+1+……+ number xn)(3)的推广式是number xi(X i+1+……+ Xn)有了这个公式的建立,针对N个彼此颜色相同奇偶性相同的元素,可以用O(n)的时间求得题目要求的值:首先O(n)的遍历i然后是O(1)的求取(2)(3)的值:sumid[i]表示编号的总和,sumni表示number的总和,havid[i]表示1到i的编号总和,havni[i]表示1到i的number总和,于是(2)(3)式子中的括号部分可以用sumid-havid[i]、sumni-havni[i]来表示。

相关文档
最新文档