NOJ1059搬寝室——数论+写法
2014-06-17 16:06
197 查看
搬寝室
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte总提交:992 测试通过:138
描述
换寝室是大家都不愿意碰到的事情,不幸的是,可怜的wwm高中大学都遇到了。
室友们有一个不成文的规定,那就是根据自己的学号选择床号。如果某同学的学号是a,并且有0..k-1一共k张床,那么他就会选择a%k号床作为他睡觉的地点。显然,两个人不能睡在一张床上。那么给出所有同学的学号,请你为他们准备一间卧室,使得里面的床的数量最少。
输入
第一行是同学的个数n(1<=n<=5,000);第2到第n+1行是每个同学的学号Si(1<=Si<=1,000,000)。
输出
仅一行,是最少的床的数目。
样例输入
5
4
6
9
10
13
样例输出
8
题目来源
wwm
分析:颇有难度!一开始暴力破解时间复杂度太高,显然Time Limit。
寻求想法(想法是多么重要!)引用:/article/8211291.html
得知可以求出两两学号的差值组成一个不重复的集合。比如:5 4 6 9 10 13组成的差值的集合为{1,2,3,4,5,6,7,9}。
说明两两的差值没有8,所以模8不会有冲突。
不过上面这种情况还存在特殊性 :)
再举个例子:1 8 13
差值的集合为{5,7,12}。那么可选的床的数量为{2,3,4,6,8,9,10,11,12...}。但是其实2,3,4,6都是不符合的,原因是它们是12的因数。
所以选择的时候要 去除 差值集合 里 的元素的因数。
想法完~
写法也有问题,一开始硬上,结果正确,但还是超时。
下面错误的写法:
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; int n, a[5000], b[10000]; int num = 0; bool yueshu(int x) // x是否差值集的约数 true是约数 { bool tag = false; for(int i=0;i<num;i++) if(b[i]%x == 0) tag = true; return tag; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n-1;i++) { for(int j=i+1;j<n;j++) { int k; for(k=0;k<num;k++) if(b[k] == fabs((a[i]-a[j])*1.0)) break; if(k >= num) b[num++] = fabs((a[i]-a[j])*1.0); } } sort(b, b+num); int i; for(i=0;i<num-1;i++) { if(b[i]+1 != b[i+1] && yueshu(i+2) == false) break; } printf("%d\n",i+2); return 0; }
其实可以换个思维,将差值记为数组的下标,1代表该差值存在,0代表该差值不存在。而关于因数的问题,循环将差值集合中的元素的因数的值赋1。
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; //搬寝室 int n; int a[5000], b[1000000]; int main() { memset(b, 0, sizeof(b)); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a, a+n); for(int i=0;i<n-1;i++) for(int j=i+1;j<n;j++) b[abs(a[i]-a[j])] = 1; int m = sqrt(a[n-1]*1.0); for(int i=2;i<=m;i++) for(int j=n/i;j<=m/i;j++) if(b[i*j] != 0) b[i] = b[j] = 1; for(int i=n;i<1000000;i++) if(b[i] == 0) { printf("%d\n",i); break; } return 0; }
相关文章推荐
- POJ 3604 Professor Ben 数论
- mysql中获取一天、一周、一月时间数据的各种sql语句写法
- 进度条的写法
- 数论 - 欧拉函数模板题 --- poj 2407 : Relatives
- memcpy内存拷贝函数的写法c++代码实例及运行结果
- 以前项目中的一些js写法
- 查表的数据来拼接insert语句的写法
- Spring切入点表达式常用写法
- Leetcode 79. Word Search 要真正理解回溯的写法!
- Django中间件工作流程及写法实例代码
- 交换a,b值的C#各种写法
- HDU 1604 (数论)
- ViewHolder写法
- Spring 拦截器的配置及 filter 的写法
- layui 时间插件, change/done,按照官网写法无效,解决方式!
- POJ 1845 Sumdiv(数论,求A^B的所有约数和)
- poj 2115 C Looooops【数论】【欧几里得算法】
- POJ 2613 Choose and divide(数论)
- phpstorm z coding zen coding功能 写法说明
- mybatis xml mapper 文件中 if-else 写法