题目1380:lucky number
转载请注明文本链接 http://blog.csdn.net/yangnanhai93/article/details/40441709
题目链接地址:http://ac.jobdu.com/problem.php?pid=1380
第一次这么正式的去写这个ACM的算法的博客,感觉这个题目给我的触动有点大,非常多时候很多其它的算法须要观察,须要细心的品味题目,才可以有:“啊哈,算法”——《编程珠玑》
先说下自己的惯性思路吧,由于这个题目就是非常明显一个统计的问题,所以,我一上来的就是尽量的去降低内存开销,所以我採用的是:
在我看来这个应该是没有问题的,由于int 4字节 char 1字节,由于m%n!=0,且n>=2,所以这个map的元素中的个数是小于等于5*5*10^5=2.5M的,然后我把代码精简,希望得到更小的开销,可是发现和使用int short作为map的开销是一样的,这个不能理解。
#include <stdio.h>
#include <map>
using namespace std; int main()
{
map<int,char> mp;
map<int,char>::iterator key;
int n,m,num;
while(scanf("%d%d",&n,&m)!= EOF)
{
mp.clear();
while(m--)
{
scanf("%d",&num);
key = mp.find(num);
if(key == mp.end())
mp.insert(pair<int,char>(num,'1'));
else if(key->second<(n+'0'))
key->second++;
}
key=mp.begin();
while(key!=mp.end()&&key->second==(n+'0'))
key++;
printf("%d\n",key->first);
}
return 0;
}
/**************************************************************
Problem: 1380
User: vincent_ynh
Language: C++
Result: Memory Limit Exceed
****************************************************************/
第二个略微能够降低空间的思路是,发现仅仅须要4位存储就能够了,然后用位去存储,这里,由于我个人的理解题目失误,误觉得是1-10^6个数,然后写了一个用位存储的代码,非常少写位操作的代码,写得比較难看,可是觉得作为一个精益求精的coder还是须要很多其它的使用的,《编程珠玑》中的第一个电话本的样例给我的触动特别大,让我感受到代码原来能够如此的巧妙,好吧,扯远了,这里贴一下,假设数据的范围小的时候,也能够使用例如以下位存储代码:
#include <stdio.h>
#include <memory.h>
int main()
{
int A[300000],B[2]={15,240};
int n,m,num;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(A,0,sizeof(A));
while(m--)
{
scanf("%d",&num);
int tmp=(num-1)/2;
int x=(num-1)%2;
if((A[tmp]&B[x])>>(4*x)<=n)
{
A[tmp]=A[tmp]+(1<<(4*x));
}
}
for(int i=1;;i++)
{
int tmp=(i-1)/2;
int x=(i-1)%2;
if(((A[tmp]&B[x])>>(4*x))%n!=0)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
/**************************************************************
Problem: 1380
User: vincent_ynh
Language: C++
Result: Runtime Error
****************************************************************/
最后就是该题我能想到的眼下最优的算法了:
我们对每个数进行二进制编码,得到的是32 位的数,假设这个数出现了n次,那么这种编码就应该出现了n次,假设对n取余,那么恰好就把这些出现n次的数消除了。想通了这个,然后接下来就是没有出现n次的,那么就是出现了m%n次的,当然能够是m%n+x*n,不影响的,在剩余的数组中,就剩下了lucky number的编码(每 位乘以m%n),所以,我们仅仅须要把数组中对每一位取余(%n)同一时候,把非0位,改为1,位不变,最后把该数组转换成整数就能够了。
代码的主要思路我们通过样例可以发现:
2 5
1 1 2 2 3
结果是3
编码得到00000001 00000001 00000010 00000010 00000011(由于数字比較小,省略了前面3位即24个0)
整合进数组之后00000033 取余之后为00000011
然后把非0的转换为1,得到00000011
把数组转换为整数为3,所以结果为3
这里补充一下“位与(&)”操作,位与(&)操作是对数字进行二进制编码,相应位假设同为1,则为1,否则为0
实际代码例如以下:
#include <stdio.h>
#include <memory.h> int main()
{
int A[32],m,n,num;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(A,0,sizeof(A));
for(int j=0;j<m;j++)
{
scanf("%d",&num);
for(int i=0;i<32;i++)
{
A[i]=A[i]+(num&1);
A[i]=A[i]%n;
num=num>>1;
}
}
int tmp=m%n,result=0;
for(int i=0;i<32;i++)
{
if(A[i]%n==tmp)
result+=1<<i; }
printf("%d\n",result);
}
return 0;
}
/**************************************************************
Problem: 1380
User: vincent_ynh
Language: C++
Result: Accepted
Time:1620 ms
Memory:1020 kb
****************************************************************/
欢迎不论什么想学习算法的人交流:vincent_ynh@163.com
题目1380:lucky number的更多相关文章
- 九度oj 题目1380:lucky number
题目描述: 每个人有自己的lucky number,小A也一样.不过他的lucky number定义不一样.他认为一个序列中某些数出现的次数为n的话,都是他的lucky number.但是,现在这个序 ...
- CF1478-B. Nezzar and Lucky Number
CF1478-B. Nezzar and Lucky Number 题意: 题目给出一个数字\(d(1\leq d \leq 9)\)代表某个人最喜欢的数字. 题目定义了幸运数字,它的含义为:若一个数 ...
- 枚举 + 进制转换 --- hdu 4937 Lucky Number
Lucky Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...
- SCU3502 The Almost Lucky Number
Description A lucky number is a number whose decimal representation contains only the digits \(4\) a ...
- HDOJ 4937 Lucky Number
当进制转换后所剩下的为数较少时(2位.3位),相应的base都比較大.能够用数学的方法计算出来. 预处理掉转换后位数为3位后,base就小于n的3次方了,能够暴力计算. . .. Lucky Numb ...
- HDU 3346 Lucky Number
水题 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> us ...
- 『NYIST』第九届河南省ACM竞赛队伍选拔赛[正式赛二]- Nearly Lucky Number(Codeforces Beta Round #84 (Div. 2 Only)A. Nearly)
A. Nearly Lucky Number time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- ZOJ 3233 Lucky Number
Lucky Number Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original I ...
- B - Nearly Lucky Number
Problem description Petya loves lucky numbers. We all know that lucky numbers are the positive integ ...
随机推荐
- iOS开发多线程篇—多线程简介
iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xc ...
- 集差集 哈希表 比较数据库的照片和server画面上,将server垃圾上的图片删除
SSH 骨架code: public String deleRubbishAd(){ int deleADcount = 0; rubbishADtp = configDao.rubbishADtp( ...
- OpenGL学习日记-2015.3.13——多实例渲染
实例化(instancing)或者多实例渲染(instancd rendering)是一种连续运行多条同样渲染命令的方法.而且每一个命令的所产生的渲染结果都会有轻微的差异. 是一种很有效的.有 ...
- Socket编程实践(4) --更复杂的过程server
1.Socket地址复用 int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); in ...
- 你所不了解的float(滥用float的怪异现象) (转)
阅读目录 float设计初衷就是为了实现文字环绕效果 如何解决浮动造成的父容器塌陷? 兼容各浏览器清除浮动的通用方式 滥用浮动 运用浮动的一些特性 浮动与布局 浮动与单侧固定布局 浮动与智能自适应的流 ...
- COC+RTS+MOR游戏开发 一(游戏特色分析,和实践)
本场比赛的临时名称 游戏特色(-):COC风格 ,塔防养成类游戏. 一款史诗般的战斗策略游戏.玩家须要建立村庄,成千上万的网友训练玩家的军队和战斗. 游戏中玩家须要不断的提高军队的作 ...
- Flex里的特效
Flex中提供了丰富的效果组件.因为效果是一种依据时间渐变的过程,因此全部效果都具有duration属性,用来设置播放时间(以毫秒为单位).也能够通过设置repeatCount属性和repeatD ...
- [linux]scp指令(转)
Linux scp命令用于Linux之间复制文件和目录,具体如何使用这里好好介绍一下,从本地复制到远程.从远程复制到本地是两种使用方式.这里有具体举例: ================== Linu ...
- 观察者模式(observer行为)c#简单的例子
观察者模式(observer行为)c#简单的例子 几点:模式使观察目标和实现松耦合之间的依赖关系.通知会传播自己主动 样本:玩家击中后发生一系列变化的敌人:后发爆炸.敌人少1一个.... namesp ...
- zTree实现访问到第一节点在相同水平当前所选节点数目
zTree实现访问到第一节点在相同水平当前所选节点数目 1.实现源代码 <!DOCTYPE html> <html> <head> <title>zTr ...