2014年百度之星程序设计大赛 - 初赛(第二轮)JZP Set
题目描述:一个{1, ..., n}的子集S被称为JZP集,当且仅当对于任意S中的两个数x,y,若(x+y)/2为整数,那么(x+y)/2也属于S。例如,n=3,S={1,3}不是JZP集,因为(1+3)/2=2不属于S。但是{1,2,3}的其他子集都属于S,所以n=3时有7个JZP集给定n,求JZP集的个数。
输入:第一行为T,表示输入数据组数。每组数据包含一行整数n。限制条件:1<=T<=10^5,1<=n<=10^7
输出:对第i组数据,输出Case #i:然后输出JZP集的个数。
这道题目考的知识主要是素数筛选,直接对每个n,求对应的JZP集肯定是会超时的(开始我也是如此,以为很简单的一道题,没想到一提交就是超时),后来用递推的思路改进下才pass。下面分享下我的答题思路:
首先,先从简单的情况分析:
n = 1时,JZP1 = {{},{1}} ,个数为2;
n = 2时,JZP2 = {{}, {1}, {2}, {1,2}},个数为4
n = 3时,JZP3 = {{}, {1}, {2}, {1,2}, {3}, {2,3}, {1,2,3}},个数为7
n = 4时,JZP4 = {{}, {1}, {2}, {1,2}, {3}, {2,3}, {1,2,3}, {4}, {3,4}, {1,4}, {2,3,4},{1,2,3,4}},个数为12
n = 5时,JZP5 = ...
从上面的JZP集合来看,一个{1...n}的集合中满足JZP的集合有:空集{},只有一个元素的集合{k}(1 <= k <= n),包含两个或两个以上元素的集合{a1,a2,a3...ak}(2 <= ak <= n,ak - ak-1 = 2 * x + 1, 0 <= x <= (n - 2)/ 2),也就是说每个满足条件的集合中的元素是等差数列,数列的差值可以取值为1,3,5,7,9...2*x+1(0 <= x <= (n - 2)/ 2)。
根据上面的思路,对每个差值1,3,5,7,9...2*x+1(0 <= x <= (n - 2)/ 2),在找出{1...n}的集合中找出满足这个差值的最大等差数列,即{1,2,3,4...n}(差值为1);{1,4,7,10...},{2,5,8,11...},{3,6,9,12...}(差值为3);{1,6,11,16...},{2,7,12,17...},{3,8,13,18},{4,9,14,19..},{5,10,15,20...}(差值为5)...。然后再这些集合中选出2个或2个以上的相邻元素作为子集合就是满足题目的JZP集。所以一个{1...n}的集合中JZP集合的个数为:1 + n + {n * (n - 1) / 2} + {(n % 3) * (n / 3) * ( n / 3 + 1) / 2 + (3 - n % 3) * (n / 3) * ( n / 3 - 1) / 2} + {(n % 5) * (n / 5) * ( n / 5 + 1) / 2 + (5 - n % 5) * (n / 5) * ( n / 5 - 1) / 2} + ...。
所以对于一个给定的n,我们可以直接求出JZP集的个数,时间复杂度为O(n),再看题目有T组数据,所以总的复杂度是O(n * T),而1<=T<=10^5,1<=n<=10^7,显然复杂度过大,容易想到的方法是提前求出n为1~10^7所对应的JZP集个数,并存在数组中,后面对每组数据,直接查数组就可以了。现在关键是怎么求n为1~10^7所对应的JZP集个数,如果还是按前面的方法对每个数n都直接求对应的JZP集的个数,复杂度为O(n^2),显然这是会超时的。可不可以利用前面n-1对应的JZP集的个数求n对应的JZP集的个数呢?如果可以这样就减少了重复计算的次数,假设dp[n - 1]表示n - 1对应的JZP集的个数,现在分析dp[n]与dp[n - 1]的关系,n相对于n-1增加的JZP集有{n},差值为1的数列中增加的JZP集为n - 1,差值为3的数列中增加的JZP集为 (n - 1) / 3,...,所以dp[n] = dp[n - 1] + 1 + (n - 1) + (n - 1) / 3 + (n - 1) / 5 + ... + 1,关键是求(n - 1) + (n - 1) / 3 + (n - 1) / 5 + ... + 1了,假设temp[n] = (n - 1) + (n - 1) / 3 + (n - 1) / 5 + ... + 1,那么temp[n] = temp[n - 1] + cn(n - 1),其中cn(n - 1)是整除n - 1的所有奇数的个数,现在问题简化为求一个数能被多少个奇数整除,用暴力肯定不行,想想这个和素数的思路差不多,素数筛选的方法能用O(nlogn)的复杂度求出1~n中的每个数被奇数整除的个数,也就是整个算法的复杂度是O(nlogn),这个时间复杂度应该够了。
有了上面的分析,实现代码就简单了,具体代码如下:
#include <iostream>
using namespace std; long long dp[];
long long cn[];
int main()
{
int t, n;
long long ans, cnt; for (int j = ; j <= ; j += )
{
for (int i = j; i <= ; i += j)
cn[i]++;
}
dp[] = ;
cnt = ;
for (int j = ; j <= ; j++)
{
cnt += cn[j - ];
dp[j] = dp[j - ] + cnt + ;
}
cin >> t;
for (int i = ; i < t; i++)
{
cin >> n;
cout << "Case #" << i + << ":" << endl << dp[n] << endl;
}
return ;
}
2014年百度之星程序设计大赛 - 初赛(第二轮)JZP Set的更多相关文章
- 2014年百度之星程序设计大赛 - 初赛(第二轮)Chess
题目描述:小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,“王”在棋盘上的走法遵循十字路线.也就是说,如果“王”当前在 ...
- HDU 4834 JZP Set(数论+递推)(2014年百度之星程序设计大赛 - 初赛(第二轮))
Problem Description 一个{1, ..., n}的子集S被称为JZP集,当且仅当对于任意S中的两个数x,y,若(x+y)/2为整数,那么(x+y)/2也属于S.例如,n=3,S={1 ...
- HDU 4833 Best Financing(DP)(2014年百度之星程序设计大赛 - 初赛(第二轮))
Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dates[ ...
- HDU 4832 Chess(DP+组合数学)(2014年百度之星程序设计大赛 - 初赛(第二轮))
Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,“王”在棋盘上的走法遵循十字路 ...
- 2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)
题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展g ...
- 2014年百度之星程序设计大赛 - 资格赛 第二题 Disk Schedule
双调欧几里得旅行商问题是一个经典动态规划问题.<算法导论(第二版)>思考题15-1和北京大学OJ2677都出现了这个题目. 旅行商问题描写叙述:平面上n个点,确定一条连接各点的最短闭合旅程 ...
- HDU6383 2018 “百度之星”程序设计大赛 - 初赛(B) 1004-p1m2 (二分)
原题地址 p1m2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- HDU6380 2018 “百度之星”程序设计大赛 - 初赛(B) A-degree (无环图=树)
原题地址 degree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))
度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
随机推荐
- bzoj 2563: 阿狸和桃子的游戏
开始写了一些东西但是后来浏览器挂了就没有存下来简直!!!!!!!!!!!!!QAQ 不想再写一遍了...总之是简单贪心. #include <iostream> #include < ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
- Java虚拟机
虚拟机每次方法的调用和返回都伴随着栈帧的入栈和出栈,而每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用(表明该栈帧执行的是哪个方法),持有这个引用是为了支持方法调用中的动态连接.这些符号引用中 ...
- Ajax是如何运行的?
1.我们需要知道什么是Ajax: AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现 ...
- IOS网络第六天 ASI (略)
**** 02-ASI01-基本使用(了解) 03-ASI02-其他用法(了解) 04-ASI03-POST请求(了解) 05-ASI04-文件下载(了解) 06-ASI05-文件上传(了解) 07- ...
- 使用 WPF+ ASP.NET MVC 开发 在线客服系统 (一)
近段时间利用业余时间开发了一套在线客服系统,期间遇到过大大小小不少问题,好在都一一解决,最终效果也还可以,打算写一个系列的文章把开发过程详细的记录下来. 希望能够和更多的开发人员互相交流学习,也希望有 ...
- 类库间无项目引用时,在编译时拷贝DLL
例一: xcopy $(TargetPath) $(SolutionDir)\Framework\HCSP.App\bin\Debug /y 例二: xcopy $(TargetPath) $(Sol ...
- Python调用C++的DLL
import os import sys from ctypes import * test = cdll.LoadLibrary('D:\Python27\py.dll') print test.A ...
- AutoMapper 最佳实践
AutoMapper 是一个基于命名约定的对象->对象映射工具. 只要2个对象的属性具有相同名字(或者符合它规定的命名约定),AutoMapper就可以替我们自动在2个对象间进行属性值的映射.如 ...
- 利用Hexo搭建个人博客-博客发布篇
通过 <利用Hexo搭建个人博客-环境搭建篇> 以及 <利用Hexo搭建个人博客-博客初始化篇>,我们了解到了利用Hexo搭建个人博客需要的环境以及配置,下面这篇文章将会介绍如 ...