1. 已知x,不用+,-,*,/符号,计算出x+1的值;
当时的分析就是分情况最后一位是0或1,最后总结出来只要把从右开始数,第一个0位置1就行了,可是我当时没有想出代码来,再此瞭望下面的代码,学习一下。。
解答:
1. 假设是整数
int Add(int x)
{
int n = x, b =1;
while( (n & b)) {
n = n& (~b); //将0后的1也转化为0
b = b < <1;
}
return (n | b);
}
还有一种解法是
x=abs((float)~x);
2. 检验一个整数是否为2的n次方数,要求用一行代码,而且不能使用循环语句。
解法:
x&(x-1)? false:true,
这个题就不知道该咋总结了,应该说是老题了,位运算,头一次见的时候,可以多试试,看看有什么规律,还是可以发现的。。
topic.csdn.net\u\20081029\10\ee84a378-bdd0-41ec-a4af-916ba59baaba.html
3.2个数组,元素数值按从小到大排序,
a[]={0,2,4,5,7,8,9,.....1000}, 从0到1000,到但有缺漏的.有900个元素.
b[]={0,1,2,3,4,5,6,.....1000}, 从0到1000,无缺漏,1001个元素
请建立一个对应的数组,元素个数等于b数组个数,也是从小大到排序.如果b数组里的数字在a里面,则数值等于b数组里的,
如果不在,则对应位为0.例如c={0,0,2,0,4,5.....1000}
请设计最优方案.
解答:
这个题出眼一想,把b中每一个元素去和a里面找,有的话,填c,没有的话,填0.。算一下复杂度,1000*900~~
如此简单~~
再想想,题不可能这么简单,要这样都会了。。都聘用了,还刷选啥,,
那么用逻辑思维怎么做这道题呢,这个题主要是求c,那么c有什么特点呢?(专注于未知数),,里面有0和一些数,关键就在这些数,有什么特点呢,可以想到当a里面有时,那么c就有(b始终都有),,,灵光一闪,怎么象函数泥,,是不是映射呢,每个a映射到c
继续,a当函数的参数,c[a[i]]=一个非零数。。这个非零数是多少呢,特例法试试:当a[i]取2时,c[2]=2,当a[3]=3,c[3]=0;a[4]=4,c[4]=4,,可以发现这个是个y=x函数,当b中的一个数,a中有时,那么这时c[i]=b[i]=a[i];没有时,a[i]=0,那么c[0]=0..。。。。。。。。
进而得到答案:
先对c所有赋初值0
完了,扫描一下a,对每个a的元素,使用:c[a[i]] = a[i];
topic.csdn.net\u\20090302\18\2A7DA801-42A9-49AE-9759-420CB6BF29F0.html
3. 一亿个整数里找出现次数最多的前N个数
解答:
首先必须明确的是,必须遍历全部的的整数才能找出,不要想什么特别的技巧,可以非常快的找出来。。
直观的,用快排将一个数排序,然后取前n个,,需要明确的是,快排不是稳定的排序,有时它的复杂度是很高的,可以达到n^2,想一想,一亿的平方,不是很小的数,,,这里有个方法“位图法”,很常用的方法:
1亿==100M
开辟200M内存够了...
array[100000000]
初始化为0
从文件里读入数据到source[100000000]数组中。
遍历source[]:
array[source[i]-1]++;
i=0...99999999
定义数组
result[N]
问题简化为:从array中选出N个下标值,它们对应了array中存储的最大的N个数。
比如array[0]=50000000,array[1]=50000000,那么result[0]=0+1=1
result[1]=1+1=2
发现上面两题之所以用嵌套数组,一个共同点就是,他们的元素是全的(0..*),本体的解法很巧妙,,,,我就不多废话了,可以多体会体会。。
topic.csdn.net\u\20080821\21\f6d4cd24-f878-419c-adc3-0928ffd3e394.html
4.求第K大的素数
如题 k=1 输出 2 k=2 输出 3
1= <k <=10000
时间限制 :1S
这个题应该不是所谓的面试题,应该算一道acm,不过感觉这道题很有意思,所以也就写到这里了。。
我当时是上外方课时想这道题的,刚开始的时候显然走了弯路,后来才意识到,这个是求第k个素数,所以需要精确的计算到第k个(素数产生并没有什么大致的规律),而不是大致的估算。。那么下面我的思路就清晰了,,只能一个一个判断了。。。
#include <iostream>
using namespace std;
long f(int *A,int k)
{
if (k==1)
{
return 2;
}
A[0]=2;
int i=3;
int index;
for (;A[k-1]==0;i+=2)
{
for (index=0;A[index]!=0;++index)
{
if (i%A[index]==0)
{
break;
}
}
if (A[index]==0)
{
A[index]=i;
}
}
return A[k-1];
}
int main()
{
int n=10000;
int *A=new int[n];
for (int i=0;i<=n-1;++i)
{
A[i]=0;
}
int k;
cin>>k;
cout<<f(A,k);
system("pause");
return 0;
}
这个是lz的代码,而我的想法差不多,唯一的区别是我是想弄个函数来判断是否是素数,而她是除以每个前面的素数来判断。。。我们俩的效率都不是很高,看下面的:
private int[] GetPrimeList(int upperValue)
{
List<int> PrimeList = new List<int>();
bool[] flags = new bool[upperValue + 2];
for (int i = 2; i <= (int)Math.Sqrt(upperValue); i++)
{
if (!flags[i])
{
for (int j = i * i; j <= upperValue; j += i)
{
flags[j] = true;
}
}
}
for (int i = 2; i < upperValue; i++)
{
if (!flags[i])
{
PrimeList.Add(i);
}
}
return PrimeList.ToArray();
}
这个叫litaoye果然很nb,他写的代码实在是比我们的好多了,可以看出来,他对素数的理解显然比我深多了,我只想着怎么数素数,素数有什么规律吗,,而他直接想到那些不是素数,,反用了书上的思想。。。很好很强大,,需要好好学习。。。
topic.csdn.net\u\20090225\22\065378f6-4cf7-4d2d-9997-ddb8a2481347.html
1. 问题描述:按顺序输入两个数a,b,转换成八位二进制表示a',b',再将这两个八位二进制数拼接成一个十六位二进制数c',规则为:将b'的八位放在c'的高位,a'的八位放到a'的地位,最后将十六位二进制数c'转换为十进制数c输出。例如:输入23(0001 0111)、14(0000 1110),c'=(0000 1110 0001 0111),最后输出c=3607,
这个题,我一看就准备用bitset了,然后直接就被题目给误导了。。。汗,,
看来自己还是对这些数的底层不熟,,组成原理没学好,,明显的,,
进制的加减其实结果都是一样,说那么多废话不过是迷惑我们。。看正解
int _tmain(int argc, _TCHAR* argv[])
{
int a = 23;
int b = 14;
cout<<a + (b<<8)<<endl;
return 0;
}
topic.csdn.net\u\20090223\20\907ff5e3-62e4-4963-8f72-279840072b50.htm