第一题的笨办法。
- int i = 0, count, tmp;
- while (1)
- {
- tmp = ++i;
- for (count = 0; count < 5; count++)
- {
- tmp = ((tmp-1) % 5 == 0)?(tmp-1)/5*4:-1;
- if (tmp <= 0)
- break ;
- }
- if (count == 5)
- break ;
- }
- printf( "The result is %d\n" , i);
int i = 0, count, tmp; while(1) { tmp = ++i; for(count = 0; count < 5; count++) { tmp = ((tmp-1) % 5 == 0)?(tmp-1)/5*4:-1; if(tmp <= 0) break; } if(count == 5) break; } printf("The result is %d\n", i);
第五题时间O(n),空间O(1)复杂度算法:
- #include <stdio.h>
- void nswapvalue( int *arr, int i , int j) {
- int m = arr[i];
- arr[i] = arr[j];
- arr[j] = -m;
- }
- void pswapvalue( int *arr, int i , int j) {
- int m = arr[i];
- arr[i] = -arr[j];
- arr[j] = m;
- }
- int swaploop( int *arr, int size){
- int cur = 0,count=0,i;
- for (i = 0 ;i < size; ++i){
- if (arr[i]>0 && cur ==0){
- cur = i;
- }
- if (arr[i]<0 && cur < i){
- nswapvalue(arr,cur,i);
- ++cur;
- ++count;
- }
- }
- for (i = count ;i < size; ++i){
- if (arr[i]>0 && cur ==0){
- cur = i;
- }
- if (arr[i]<0 && cur < i){
- pswapvalue(arr,cur,i);
- ++cur;
- }
- }
- }
#include <stdio.h> void nswapvalue(int *arr,int i , int j) { // change positive to negative int m = arr[i]; arr[i] = arr[j]; arr[j] = -m; } void pswapvalue(int *arr,int i , int j) {//change negative to positive int m = arr[i]; arr[i] = -arr[j]; arr[j] = m; } int swaploop(int *arr,int size){//思想:执行一次循环,把所有负数置换到前面,可以保证负数的相对位置不变 int cur = 0,count=0,i; for(i = 0 ;i < size; ++i){ // 把所有负数提前,并把置换到后面的整数变为负数 if(arr[i]>0 && cur ==0){ cur = i; //cur 始终指向最前面的整数 } if(arr[i]<0 && cur < i){ nswapvalue(arr,cur,i); ++cur; ++count; //记录负数的个数 } } for(i = count ;i < size; ++i){ //处理原始负数以后的数据,并把上面变为负数的正数变回来 if(arr[i]>0 && cur ==0){ cur = i; } if(arr[i]<0 && cur < i){ pswapvalue(arr,cur,i); ++cur; } } }
回复renenglish:已通过程序验证,结果不对
输入int arr[10] = { -1,2,3,4,-5,6,-7,8,-9,10 };
int size = 10;
出来的结果是:-1,-5,-7,-9,3,4,-2,8,6,10;
请验证!
人人笔试题1:
int fun(int n)
{
int f;
if(n <= 3)
{
f = pow(double(2),(n-1));
}
else
{
f = fun(n - 1) + fun(n - 2) + fun(n - 3);
}
return f;
}
int main(void)
{
int n = 7;//台阶总数
int sum;
sum = fun(n);
printf("%d\n",sum);
}
回复jijiyuyisheng:这样递归重复计算很多,有两种方法
1.迭代
- int GetMaxStepNormal( int n)
- {
- if (n<=0) return 0;
- if (n==1) return 1;
- if (n==2) return 2;
- if (n==3) return 4;
-
- int r,r1=1,r2=2,r3=4;
-
- for ( int i=3;i<n;i++)
- {
- r=r1+r2+r3;
- r1=r2;
- r2=r3;
- r3=r;
- }
- return r;
- }
int GetMaxStepNormal(int n) { if(n<=0) return 0; if(n==1) return 1; if(n==2) return 2; if(n==3) return 4; int r,r1=1,r2=2,r3=4; for(int i=3;i<n;i++) { r=r1+r2+r3; r1=r2; r2=r3; r3=r; } return r; }
2.递归,注意保存以计算的结果
- <BR> int GetMaxStepMain( int , int *);<BR> int GetMaxStepRecurs( int n)<BR>{<BR> int * calc;<BR> int r;<BR> if (n<=0) return 0;<BR> calc= new int [n];<BR> if (NULL==calc) return 0;<BR> for ( int i=0;i<n;++i) calc<I>=0;<BR> r= GetMaxStepMain(n,calc);<BR> delete calc;<BR> return r;<BR>}<BR> int GetMaxStepMain( int n, int * a)<BR>{<BR> int t[3];<BR> if (n==1) return 1;<BR> if (n==2) return 2;<BR> if (n==3) return 4;<BR> <BR> for ( int i=3;i>0;i--)<BR> {<BR> if (a[n-i]==0) <BR> {<BR> t[i-1]=GetMaxStepMain(n-i,a);<BR> a[n-i]=t[i-1];<BR> }<BR> else <BR> {<BR> t[i-1]=a[n-i];<BR> }<BR> }<BR> return t[0]+t[1]+t[2];<BR>}<BR>
int GetMaxStepMain(int ,int*);
int GetMaxStepRecurs(int n)
{
int* calc;
int r;
if(n<=0) return 0;
calc=new int[n];
if(NULL==calc) return 0;
for(int i=0;i<n;++i) calc=0;
r= GetMaxStepMain(n,calc);
delete calc;
return r;
}
int GetMaxStepMain(int n,int* a)
{
int t[3];
if(n==1) return 1;
if(n==2) return 2;
if(n==3) return 4;
for(int i=3;i>0;i--)
{
if(a[n-i]==0)
{
t[i-1]=GetMaxStepMain(n-i,a);
a[n-i]=t[i-1];
}
else
{
t[i-1]=a[n-i];
}
}
return t[0]+t[1]+t[2];
}
第三题O(n)复杂度算法:
- #include <stdio.h>
- #include <string.h>
- int brothstr( const char *s1, int len1, const char *s2, int len2){
- if (len1 != len2) return 0;
- int box[128] = {0};
- int i;
-
- for (i=0;i<len1;++i){
- int v = s1[i];
- ++box[v];
- }
-
- for (i=0;i<len2;++i){
- int v = s2[i];
- --box[v];
- }
-
- for (i=0;i<len1;++i){
- int v = s1[i];
- if (box[v]>0) return 0;
- }
- return 1;
- }
- int main( int argc, const char *argv[])
- {
- if (argc!=3){
- printf( "%s s1 s2\n" ,argv[0]);
- return 1;
- }
- char *s1 = ( char *)argv[1];
- int l1 = strlen(s1);
- char *s2 = ( char *)argv[2];
- int l2 = strlen(s2);
-
- int isborther = brothstr(s1,l1,s2,l2);
- isborther? printf( "is brother\n" ,s1,s2):printf( "is not brother\n" ,s1,s2);
- return 0;
- }
#include <stdio.h> #include <string.h> int brothstr(const char *s1,int len1,const char *s2,int len2){ if(len1 != len2)return 0; int box[128] = {0}; int i; //pack into box for(i=0;i<len1;++i){ int v = s1[i]; ++box[v]; } //remove from box for(i=0;i<len2;++i){ int v = s2[i]; --box[v]; } // is the box empty? for(i=0;i<len1;++i){ int v = s1[i]; if(box[v]>0)return 0; } return 1; } int main(int argc, const char *argv[]) { if(argc!=3){ printf("%s s1 s2\n",argv[0]); return 1; } char *s1 = (char*)argv[1]; int l1 = strlen(s1); char *s2 = (char*)argv[2]; int l2 = strlen(s2); int isborther = brothstr(s1,l1,s2,l2); isborther? printf("is brother\n",s1,s2):printf("is not brother\n",s1,s2); return 0; }
第23题: 思路先建立数学模型,设3步的走 i 次,2步的走 j 次, 1步的走 k 次,上了3*i + 2*j + 1*k = n个台阶.总共走 i + j + k 次, 等于把n个台阶的长度先划分成 i + j + k 个段落, 然后分别填下i个3, j 个2, k个1.这样,当划分成 i + j + k 个段落时, 根据排列组合知识,所有填充方法有 (i + j + k )!/ ( i!*j!*k!) 种,程序中使用GetComb(i,j,k)函数计算此值. 在下一页贴上.
对于i, j, k的确定,我们可以用从大到小划分法, 先划分3的次数,再划分2的次数,剩下的都算做1的次数,具体程序中就是里面的i,j,两重循环.
-
-
-
- int CItems::NStepFor123( int n)
- {
- int i=0;
- int j=0;
- int p;
- int k;
- int result=0;
- for ( i=0; i<=n/3; i++ )
- {
- p = n-i*3;
- for ( j=0; j<=p/2; j++ )
- {
- k = p -j*2;
-
- result += GetComb(i,j,k);
- }
- }
- return result;
- }
//23、人人笔试1:一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法? //思路,建模分析得出结果是 所有 (i+j+k)!/(i!*j!*k!) 的和,其中i,j,k满足条件 3*i+2*j+k=n //以下解法暂不考虑数据过大的溢出问题 int CItems::NStepFor123(int n) { int i=0; int j=0; int p; int k; int result=0; for ( i=0; i<=n/3; i++ ) { p = n-i*3; for ( j=0; j<=p/2; j++ ) { k = p -j*2; //求(i+j+k)!/(i!*j!*k!) result += GetComb(i,j,k); } } return result; }
回复eagleatustb:续上:
- int CItems::GetComb( int i, int j, int k)
- {
- if ( i+j+k<0 || i<0 || j<0 || k<0)
- {
- return 0;
- }
- int den=1;
- int mun=1;
- int p;
-
- for ( p = 1;p<=i+j+k; p++ )
- {
- mun*=p;
- }
-
- if (i>0)
- {
- for ( p = 1;p<=i; p++ )
- {
- den*=p;
- }
- }
-
- if (j>0)
- {
- for ( p = 1;p<=j; p++ )
- {
- den*=p;
- }
- }
-
- if (k>0)
- {
- for ( p = 1;p<=k; p++ )
- {
- den*=p;
- }
- }
- return ( int )(mun/den);
- }
int CItems::GetComb(int i,int j,int k) { if ( i+j+k<0 || i<0 || j<0 || k<0) { return 0; } int den=1;//分母 int mun=1;//分子 int p; //临时变量 for ( p = 1;p<=i+j+k; p++ )//求分子 { mun*=p; } if (i>0) //求分母中i!部分 { for ( p = 1;p<=i; p++ ) { den*=p; } } if (j>0)//求分母中i!j!部分 { for ( p = 1;p<=j; p++ ) { den*=p; } } if (k>0)//求分母总值 { for ( p = 1;p<=k; p++ ) { den*=p; } } return (int)(mun/den);//可以用数学方法证明此除法得出的一定是整数 }
回复eagleatustb: CItems item;
int StepRes1;
for ( int i =1; i<20; i++ )
{
StepRes1 = item.NStepFor123(i);
printf("\n%d step for 1,2,3 method is %d",i,StepRes1);
}
结果如下:
1 step for 1,2,3 method is 1
2 step for 1,2,3 method is 2
3 step for 1,2,3 method is 4
4 step for 1,2,3 method is 7
5 step for 1,2,3 method is 13
6 step for 1,2,3 method is 24
7 step for 1,2,3 method is 44
8 step for 1,2,3 method is 81
9 step for 1,2,3 method is 149
10 step for 1,2,3 method is 274
11 step for 1,2,3 method is 504
12 step for 1,2,3 method is 927
13 step for 1,2,3 method is1705
14 step for 1,2,3 method is 3127
15 step for 1,2,3 method is 5691
16 step for 1,2,3 method is 10185
17 step for 1,2,3 method is 17695
18 step for 1,2,3 method is 29465
19 step for 1,2,3 method is 46435
- document.write( "没一个会的!" )
document.write("没一个会的!")
顶一个
21题
-
-
-
-
- #define MAX_ARRAY_SIZE 9
- void CItems::GetMultiplay()
- {
- int Array[MAX_ARRAY_SIZE]={1,2,3,4,5,6,7,8,9};
- int temp1[MAX_ARRAY_SIZE]={0};
- int temp2[MAX_ARRAY_SIZE]={0};
-
- temp1[0] = Array[0];
- temp2[MAX_ARRAY_SIZE-1] = Array[MAX_ARRAY_SIZE-1];
- for ( int j=1; j<MAX_ARRAY_SIZE; j++ )
- {
- temp1[j] = temp1[j-1]*Array[j];
- temp2[MAX_ARRAY_SIZE-1-j] = temp2[MAX_ARRAY_SIZE-j]*Array[MAX_ARRAY_SIZE-1-j];
- }
- Array[0] = temp2[1];
- Array[MAX_ARRAY_SIZE-1] = temp1[MAX_ARRAY_SIZE-2];
- for ( int i = 1; i<MAX_ARRAY_SIZE-1; i++ )
- {
- Array[i]=temp1[i-1]*temp2[i+1];
- }
-
- for ( int k = 0; k<MAX_ARRAY_SIZE; k++ )
- {
- printf( "Array[%d]=%d" ,i,Array[i]);
- }
- return ;
- }
//搜狗笔试题:一个长度为n的数组a[0],a[1],...,a[n-1]。现在更新数组的名个元素,即a[0]变为a[1]到a[n-1]的积,a[1]变为a[0]和a[2]到a[n-1]的积,...,a[n-1]为a[0]到a[n-2]的积。 //程序要求: //要求具有线性复杂度。 //不能使用除法运算符。 #define MAX_ARRAY_SIZE 9 void CItems::GetMultiplay() { int Array[MAX_ARRAY_SIZE]={1,2,3,4,5,6,7,8,9}; int temp1[MAX_ARRAY_SIZE]={0}; int temp2[MAX_ARRAY_SIZE]={0}; temp1[0] = Array[0]; temp2[MAX_ARRAY_SIZE-1] = Array[MAX_ARRAY_SIZE-1]; for ( int j=1; j<MAX_ARRAY_SIZE; j++ ) { temp1[j] = temp1[j-1]*Array[j]; temp2[MAX_ARRAY_SIZE-1-j] = temp2[MAX_ARRAY_SIZE-j]*Array[MAX_ARRAY_SIZE-1-j]; } Array[0] = temp2[1]; Array[MAX_ARRAY_SIZE-1] = temp1[MAX_ARRAY_SIZE-2]; for ( int i = 1; i<MAX_ARRAY_SIZE-1; i++ ) { Array[i]=temp1[i-1]*temp2[i+1]; } for ( int k = 0; k<MAX_ARRAY_SIZE; k++ ) { printf("Array[%d]=%d",i,Array[i]); } return ; }
回复eagleatustb:具体描述下你的思路吧。
mark下 留着以后看
第13题,毒药的问题:
- int cacl( int mouse_count, int bottle_count)
- {
- int res = 0;
-
- for ( i = 1; i <= mouse_count; i++ ) {
- res += bottle_count/(1<<i);
- }
-
- return res;
- }
int cacl(int mouse_count, int bottle_count) { int res = 0; for ( i = 1; i <= mouse_count; i++ ) { res += bottle_count/(1<<i); } return res; }
有点意思!
第二题,不知此解如何?
- int rand10()
- {
- int a, b;
-
- do {
- a = rand7();
- } while ( a > 5 );
-
- do {
- b = rand7();
- } while ( b > 2 );
-
- return a*2-(b-1);
- }
int rand10() { int a, b; do { a = rand7(); } while ( a > 5 ); do { b = rand7(); } while ( b > 2 ); return a*2-(b-1); }
各种招聘进行中啊。
最近太多了,暂时不看了。
mark一下。
很好的东西,我收藏了
求rand(10)这个简单做法是:
private int getRand10()
{
int a=rand(7);
int b=rand(7);
if((a+b)<11)
return a+b;
}
mark
望洋兴叹~啊
真是好东西啊
额。。。待我好好想想
[quote=csucdl]16题 不完整
- char const * MI(string const &...[/quote]
- 接着
- [code=cpp]
- char const * Add(string& x, string const & y)
- {
- char const * px = x.c_str();
- char const * py = y.c_str();
- char const * pxe = px + x.length();
- char const * pye = py + y.length();
- int carry = 0;
- list< char > r;
-
- for (--pxe, --pye; pxe >= px && pye >= py; --pxe, --pye)
- {
- int i = (*pxe - '0' ) + (*pye - '0' ) + carry;
- carry = i / 10;
- i %= 10;
- r.push_front(i + '0' );
- }
-
- for (; pxe >= px; --pxe)
- {
- int i = (*pxe - '0' ) + carry;
- carry = i / 10;
- i %= 10;
- r.push_front(i + '0' );
- }
-
- for (; pye >= py; --pye)
- {
- int i = (*pye - '0' ) + carry;
- carry = i / 10;
- i %= 10;
- r.push_front(i + '0' );
- }
-
- return x.assign(r.begin(), r.end() ).c_str();
- }
char const* MI(string const&...[/quote] 接着 [code=cpp] char const* Add(string& x, string const& y) { char const* px = x.c_str(); char const* py = y.c_str(); char const* pxe = px + x.length(); char const* pye = py + y.length(); int carry = 0; list<char> r; for (--pxe, --pye; pxe >= px && pye >= py; --pxe, --pye) { int i = (*pxe - '0') + (*pye - '0') + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } for (; pxe >= px; --pxe) { int i = (*pxe - '0') + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } for (; pye >= py; --pye) { int i = (*pye - '0') + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } return x.assign(r.begin(), r.end() ).c_str(); }
16题 不完整
- char const * MI(string const & x, int y, int z, string &s)
- {
- list< char > r;
- int carry = 0;
- for ( char const * p = x.c_str(), *pe = x.c_str() + x.length() - 1; pe >= p; --pe)
- {
- int i = (*pe - '0' ) * y + carry;
- carry = i / 10;
- i %= 10;
- r.push_front(i + '0' );
- }
-
- if (carry > 0)
- {
- r.push_front(carry + '0' );
- }
-
- for (; z > 0; --z)
- {
- r.push_back( '0' );
- }
-
- return s.assign(r.begin(), r.end() ).c_str();
- }
char const* MI(string const& x, int y, int z, string &s) { list<char> r; int carry = 0; for (char const* p = x.c_str(), *pe = x.c_str() + x.length() - 1; pe >= p; --pe) { int i = (*pe - '0') * y + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } if (carry > 0) { r.push_front(carry + '0'); } for (; z > 0; --z) { r.push_back('0'); } return s.assign(r.begin(), r.end() ).c_str(); }
第三题用了排序,那不是完全没难度了。。。
三题为什么不用排序,把它们都排序,再比较
我用的都是java自带的排序
import java.util.Arrays;
public class Test{
public static void main(String[] args)
{
String str1="abc";
String str2="bca";
char[] arr1=str1.toCharArray();
char[] arr2=str2.toCharArray();
Arrays.sort(arr1);
Arrays.sort(arr2);
str1=new String(arr1);
str2=new String(arr2);
if(str1.equals(str2)){
System.out.println("是兄弟串");
}else{
System.out.println("不是兄弟串");
}
}
}
做个记号,闲下来是看看
第五题
- void PartitionSort( int q[], int n)
- {
- for ( int i=n-1, k=0; i>=0; i--)
- {
- if (q[i] >= 0)
- {
- if (k == 0) continue ;
- int t = q[i];
- memmove(&q[i], &q[i+1], k* sizeof ( int ));
- q[i+k] = t;
- }
- else
- k++;
- }
- }
void PartitionSort(int q[], int n) { for (int i=n-1, k=0; i>=0; i--) { if (q[i] >= 0) { if (k == 0) continue; int t = q[i]; memmove(&q[i], &q[i+1], k*sizeof(int)); q[i+k] = t; } else k++; } }
多年以后发现自己是门外汉
- int total = 0;
- for ( int i = 0; i < 10; i++)
- {
- total += Rand7();
- }
- return total / 7;
int total = 0; for (int i = 0; i < 10; i++) { total += Rand7(); } return total / 7;
110楼的兄弟很NB啊!!
这个方法有点强盗逻辑,OTZ不过确实很巧妙……
第二题应该可以做:
- int rand7();
- int Random10()
- {
- int k, i;
- while (1)
- {
- int i = rand7();
- if (i < 6)
- {
- k = i;
- break ;
- }
- }
- while (1)
- {
- int i = rand7();
- if (i < 7)
- {
- if (i < 4)
- {
- k = k + 5;
- }
- break ;
- }
- }
- return k;
- }
int rand7(); int Random10() { int k, i; while(1) { int i = rand7(); if(i < 6) { k = i; break; } } while(1) { int i = rand7(); if(i < 7) { if(i < 4) { k = k + 5; } break; } } return k; }
居然一题都不会,悲哀。
第一题的递归算法
- int X( int iMonkey, int & iPerMonkey)
- {
- if (1 == iMonkey)
- {
- return 5 * iPerMonkey + 1;
- }
- int iLeft = X(iMonkey - 1, iPerMonkey);
- while (iLeft % 4)
- {
- iLeft = X(iMonkey - 1, ++iPerMonkey);
- }
- return 1 + 5 * iLeft / 4;
- }
int X(int iMonkey, int& iPerMonkey) { if (1 == iMonkey) { return 5 * iPerMonkey + 1; } int iLeft = X(iMonkey - 1, iPerMonkey); while (iLeft % 4) { iLeft = X(iMonkey - 1, ++iPerMonkey); } return 1 + 5 * iLeft / 4; }
第一个是数学中一个数列的求和为题;定义sn为数列和(桃子数目),n为猴子数目。a1,a2。。。为数列的第一项和第二项。则sn=a1+n-1+(n-1)/n-(a1+a2+a3+。。。+an-1)/n+n。根据这个题目a1=(sn/n)+1,a2=(sn-a1)/n+1..那个sn的应该可以计算出来是关于n的函数(目前木有计算)
实现如下:
import java.util.Set;
import java.util.TreeSet;
public class BrotherComparator {
Set<Character> set = null;
public BrotherComparator(String a) {
if (a == null)
set = null;
else {
set = new TreeSet<Character>();
for (int i = 0; i < a.length(); i++) {
set.add(a.charAt(i));
}
}
}
public Set<Character> getSet() {
return set;
}
public void setSet(Set<Character> set) {
this.set = set;
}
public boolean compareBrother(BrotherComparator brother) {
if (brother == null || brother.getSet() == null)
return false;
if (brother == this)
return true;
if (brother.getSet().toString().equals(set.toString()))
return true;
else
return false;
}
public static void main(String[] args) {
BrotherComparator a = new BrotherComparator("abd");
BrotherComparator b = new BrotherComparator("bda");
BrotherComparator c = null;
System.out.println(a.compareBrother(b));
}
}
最后输出结构true;
第三题主要考虑数据结构问题,如果我们能找一个能存储字符并且能够自动排序每一个录入的字符,最后比较一下就可以了。
JAVA 符合这样的数据结构有TreeSet.
第三题我是这样做的,代码挺简单的,效率不怎么样。
- #include<iostream>
- using namespace std;
-
- int main()
- {
- char ch[100],ch1[100];
- int a[27],b[27];
- while (cin >> ch >> ch1)
- {
- memset(a,0,27* sizeof ( int ));
- memset(b,0,27* sizeof ( int ));
- int len1 = strlen(ch);
- int len2 = strlen(ch1);
- if (len1 != len2)
- {
- cout<< "不是兄弟字符串" <<endl;
- continue ;
- }
- for ( int i=0;i<len1;i++)
- {
- a[( int )ch[i] - 97]++;
- }
- for (i=0;i<len2;i++)
- {
- b[( int )ch1[i] - 97]++;
- }
- int flag=1;
- for (i=0;i<27;i++)
- {
- if (a[i] != b[i])
- {
- flag=0;
- break ;
- }
- }
- if (flag)
- {
- cout<< "是兄弟字符串" <<endl;
- }
- else
- {
- cout<< "不是兄弟字符串" <<endl;
- }
- }
- }
#include<iostream> using namespace std; int main() { char ch[100],ch1[100]; int a[27],b[27]; while(cin >> ch >> ch1) { memset(a,0,27*sizeof(int)); memset(b,0,27*sizeof(int)); int len1 = strlen(ch); int len2 = strlen(ch1); if(len1 != len2) { cout<<"不是兄弟字符串"<<endl; continue; } for(int i=0;i<len1;i++) { a[(int)ch[i] - 97]++; } for(i=0;i<len2;i++) { b[(int)ch1[i] - 97]++; } int flag=1; for(i=0;i<27;i++) { if(a[i] != b[i]) { flag=0; break; } } if(flag) { cout<<"是兄弟字符串"<<endl; } else { cout<<"不是兄弟字符串"<<endl; } } }
第五题睡觉的时候想了睡着了,找不到o(n),o(1)的方法,有点沮丧
引用“lovewhatilove”的评论:
回复erlangxiong:我看了下,怎么是无解呢?从后向前,找一个负数,...
如果只有一负数,并且在数组的最后一位。何解?
- 如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
- #define TABLE_SIZE 256
-
- int main()
- {
- char string1[1000]= "bad" ;
- char string2[1000]= "adb" ;
- char *pstring1 ;
- char *pstring2 ;
- unsigned int hash_table[TABLE_SIZE] = {0};
- unsigned int index = 0;
-
- pstring1 = string1;
- pstring2 = string2;
-
- while (*pstring1){
- hash_table[*pstring1]+=1;
- printf( "%d\r\n" , *pstring1);
- pstring1++;
- }
-
- while (*pstring2){
- hash_table[*pstring2]-=1;
- printf( "%d\r\n" , *pstring2);
- pstring2++;
- }
-
-
- for (index = 0; index < TABLE_SIZE ; index++)
- if (hash_table[index]!=0)
- break ;
-
- if (index == TABLE_SIZE)
- printf( "%s == %s\r\n" , string1, string2);
- else
- printf( "%s != %s\r\n" , string1, string2);
-
- getchar();
-
- return 0;
- }
如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。 #define TABLE_SIZE 256 int main() { char string1[1000]="bad"; char string2[1000]="adb"; char *pstring1 ; char *pstring2 ; unsigned int hash_table[TABLE_SIZE] = {0}; unsigned int index = 0; pstring1 = string1; pstring2 = string2; while(*pstring1){ hash_table[*pstring1]+=1; printf("%d\r\n", *pstring1); pstring1++; } while(*pstring2){ hash_table[*pstring2]-=1; printf("%d\r\n", *pstring2); pstring2++; } for(index = 0; index < TABLE_SIZE ; index++) if(hash_table[index]!=0) break; if(index == TABLE_SIZE) printf("%s == %s\r\n", string1, string2); else printf("%s != %s\r\n", string1, string2); getchar(); return 0; }
回复l1212s:是否简单描述下你的思路?
另外一种算法的:
public class Test {
/**
* 计算猴子分桃最少数,最后一只猴子不能吃桃,只能带走一个桃子。
* @param ave 最少基数
* @param count 猴子个数
* @param c 分桃次数,每次减1
* @return
*/
public static int split(int ave, int count, int c) {
int t = 1;
if (c != 1)
t = ave * (c) + 1;
System.out.println(c + "->" + t);
c++;
if (c == count + 1) {
return t;
} else {
return split(t, count, c);
}
}
public static void main(String args[]) throws Exception {
System.out.println("mix=" + split(1, 5, 1));
}
}
输入结果:
1->1
2->3
3->10
4->41
5->206
mix=206
回复jerryh2008:每个猴子还要拿走一堆呢
如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
#define TABLE_SIZE 256
int main()
{
char string1[1000]="bad";
char string2[1000]="adb";
char *pstring1 ;
char *pstring2 ;
unsigned int hash_table[TABLE_SIZE] = {0};
unsigned int index = 0;
pstring1 = string1;
pstring2 = string2;
while(*pstring1){
hash_table[*pstring1]+=1;
printf("%d\r\n", *pstring1);
pstring1++;
}
while(*pstring2){
hash_table[*pstring2]-=1;
printf("%d\r\n", *pstring2);
pstring2++;
}
for(index = 0; index < TABLE_SIZE ; index++)
if(hash_table[index]!=0)
break;
if(index == TABLE_SIZE)
printf("%s == %s\r\n", string1, string2);
else
printf("%s != %s\r\n", string1, string2);
getchar();
return 0;
}
第一题JAVA答案:
public class Test {
public static int split(int ave, int count, int c) {
int i = c;
int t = ave * (c++) + 1;
System.out.println(i + "->" + t);
if (c == 6) {
return t;
} else {
return split(t, count, c);
}
}
public static void main(String args[]) throws Exception {
System.out.println("mix=" + split(1, 5, 1));
}
}
肯定基数为1是最少数,既最后一只猴子吃掉一个,最后拿走一个。如果最后一只猴子不能吃,只能拿走那自己考虑了。
输入结果:
1->2
2->5
3->16
4->65
5->326
mix=326
第一题猴子分桃子,有五个猴子的时候桃子的数目为X=3125a+3121,其中a>=0。如果取最小,那么就是X(a=0)=3121了。具体计算方法见 http://blog.csdn.net/denieljean/article/details/6825777
收藏
第三题,计算每个字符串的特征值,可以保存在int a[26];
下标0->25对应26个字母,数组的值为每个字符出现的次数,需要每个字符串遍历一遍才能得到特征值,插入特征值时就可以按大小排列成链表,到之后显示链表即可
第二题如果不考虑性能的话,最简单的做法是
rand7做10次,然后累加以后对10取模后+1
第一题
#include <stdio.h>
int a(int num, int split, int eat)
{
if (num == 1)
return num * split + eat;
else
return a(num - 1, split, eat) * split + eat;
}
int main()
{
printf("total: %d\n", a(5, 5, 1));
}
13题解答
任意一只喝一瓶
任意两只喝一瓶
任意三只喝一瓶
任意四只喝一瓶
任意五只喝一瓶
结果为
c5(1)+c5(2)+c5(3)+c5(4)+c5(5)=31
对哦,第二题应该是个概率统计的问题,将七分之一的概率变成十分之一的概率。
第二题的解答
在7进制下构造一个[0,1) 的随机函数,如下:
random()=(rand7()-1)/7+(rand7()-1)/7*7+(rand7()-1)/7*7*7+(rand7()-1)/7*7*7*7
有了[0,1) 的随机函数,剩下的都好办了
变态的题目,等高手解答!
楼主,你第二题方法的第二步貌似写的有问题?
我觉得应该是:
1.两次得到随机数 a1 a2 ;
2.如果 a1*7+a2<48 则 b=(a1*7+a2)/4-1 否则重复第一步;
非常感谢你的思路
哥们,认真点,不是你想的这么简单的。。。 你的方法明显顺序变了,不理解的话,动手写出程序能说明问题。这题主要是复杂度无法到达所说的时间O(n),空间O(1). 所以说无解,并不是说不能实现顺序不变的分开正负数.
引用“lovewhatilove”的评论:
回复iicup:我看了下,怎么是无解呢?从后向前,找一个负数,往前找个正数...
朋友,你有加上文中所公布的Algorithms群了么。希望,认识下你。
这是在考数学了,数学知识好的话,应该问题不大。
第5题,CSDN上有一篇帖子,讨论的最后结果是“无解”
回复iicup:我看了下,怎么是无解呢?从后向前,找一个负数,往前找个正数,交换位置,这样交换下去,最终交换完毕,结果自然就出来~正数,负数顺序自然不变的。
rand7()+rand()%4
回复day_learn:取1时只能是1+0
取2时可以是1+1、2+0
。。。
所以1-10不等概率。。。
回复sunjiankirk:你的不行吧??????相对位置要不变
第一题: 从第五个开始往第一猴倒着推算.
第二题:
( rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() ) / 7
第三题: unsigned int count[24] ; 统计各个字符出现的次数,然后比较
第四题: IP 地址划分成两段数字,前一部分按照顺序排列,另外一部分按照hash表,在第二部分,最近查找的可以移到前面,没有经验,不知道是个什么规律。
第五题:依据快速排序的思想,排序一次就可以了,设置用来比较的 middle value = 0;
回复csl19972000:加10次 结果为10~70
10-70出现的机会必然是中间大,两头小,况且:
10、11、12、13除7取整为1
14、15、16、17、18、19、20除7取整为2
。。。。
1-10每个数机会不是1/10 。。。
回复csl19972000:我可以证明这种方法是概率分布不平均的,因为只用证明这种方法不正确,不需要详细的逻辑推理,使用枚举法得到答案:
1: 28250575
2: 28249980
3: 28248440
4: 28246570
5: 28245085
6: 28244524
7: 28245085
8: 28246570
9: 28248440
10:28249980
- int Array[7]={1,2,3,4,5,6,7};
- int Result[10]={0};
- for ( int a1 = 0;a1<7;a1++ )
- { for ( int a2 = 0;a2<7;a2++)
- { for ( int a3 = 0;a3<7;a3++)
- { for ( int a4 = 0;a4<7;a4++)
- { for ( int a5 = 0;a5<7;a5++)
- { for ( int a6 = 0;a6<7;a6++)
- { for ( int a7 = 0;a7<7;a7++)
- { for ( int a8 = 0;a8<7;a8++)
- { for ( int a9 = 0;a9<7;a9++)
- { for ( int a10 = 0;a10<7;a10++)
- { int k = Array[a1]+Array[a2]+Array[a3]+Array[a4]+Array[a5]
- +Array[a6]+Array[a7]+Array[a8]+Array[a9]+Array[a10];
- k = k%10;
- Result[k]++;
- }}}}}}}}}}
- for ( int j=0; j<10;j++ )
- printf( "\nResult[%d] Count is :%d " ,j,Result[j]);
int Array[7]={1,2,3,4,5,6,7}; int Result[10]={0}; for ( int a1 = 0;a1<7;a1++ )//1 {for (int a2 = 0;a2<7;a2++)//2 {for (int a3 = 0;a3<7;a3++)//3 { for (int a4 = 0;a4<7;a4++)//4 {for (int a5 = 0;a5<7;a5++)//5 {for (int a6 = 0;a6<7;a6++)//6 {for (int a7 = 0;a7<7;a7++)//7 {for (int a8 = 0;a8<7;a8++)//8 {for (int a9 = 0;a9<7;a9++)//9 {for (int a10 = 0;a10<7;a10++)//10 {int k = Array[a1]+Array[a2]+Array[a3]+Array[a4]+Array[a5] +Array[a6]+Array[a7]+Array[a8]+Array[a9]+Array[a10]; k = k%10; Result[k]++; }}}}}}}}}} for ( int j=0; j<10;j++ ) printf("\nResult[%d] Count is :%d ",j,Result[j]);
而楼主发的那种方法显然不太稳定,依赖于rand7()产生两数积少于40,目前我也没找到更好的解决方法。
第5题,思路是一正一反,每次循环会设置好一个正数和一个负数的位置。
-
- int xsort( int *data, int size)
- {
- int neg_num = 0;
- int pos_p, neg_p;
- int i, j;
- for (i = 0; i < size; i++)
- if (data[i] < 0)
- neg_num++;
- int pos_num = 0;
- for (i = 0; i < neg_num; i++)
- if (data[i] >=0)
- pos_num++;
-
- i = 0, j = size -1;
- pos_p = neg_num;
- neg_p = neg_num - 1;
- while (pos_num > 0){
- while (data[i] < 0) i++;
- int tmp = data[i];
- int k = i;
- while (k++ < neg_p)data[k-1] = data[k];
- while (data[j] >=0)j--;
- data[neg_p--] = data[j];
- k = j;
- while (k-- > pos_p)data[k+1] = data[k];
- data[pos_p++] = tmp;
- pos_num--;
- }
- return neg_num;
- }
//return:negative count int xsort(int *data, int size) { int neg_num = 0; int pos_p, neg_p; int i, j; for(i = 0; i < size; i++)//总的负数个数 if(data[i] < 0) neg_num++; int pos_num = 0; for(i = 0; i < neg_num; i++) if(data[i] >=0) pos_num++; i = 0, j = size -1; pos_p = neg_num; neg_p = neg_num - 1; while(pos_num > 0){ while(data[i] < 0) i++;//找正数 int tmp = data[i]; int k = i; while(k++ < neg_p)data[k-1] = data[k];//腾出了负数的位置 while(data[j] >=0)j--;//找负数 data[neg_p--] = data[j];//负数搁进去 k = j; while(k-- > pos_p)data[k+1] = data[k];//腾出了正数的位置 data[pos_p++] = tmp;//正数搁进去 pos_num--; } return neg_num; }
回复x313695373:恩 结果可以达到要求;
时间复杂度我觉得是
O(N) //求负数个数
+ O(N) //求pos_num
+ k*( O(N)+O(N)+O(N)+O(N)) //pos_num次大循环中的四次遍历。
= k*O(N);
k为负数的个数前面部分的正数个数pos_num 。
按说k为常数 故 时间复杂度也可以达到要求。
回复x313695373:sorry,这个不对,达不到O(N)的要求
第二题:
- int n = 0;
- int m = 0;
- int p = -1;
- while (n == 0) {
- m = rand7();
- if (m == 6) {
- p = 0
- }
- else if (m == 7) {
- p = 5;
- }
- else {
- if (p >= 0) {
- n = m + p;
- }
- }
- }
- return n;
int n = 0; int m = 0; int p = -1; while (n == 0) { m = rand7(); if (m == 6) { p = 0 } else if (m == 7) { p = 5; } else { if (p >= 0) { n = m + p; } } } return n;
回复sadfishsc:这个好高深- -
第二题 rand7()+ rand7()再判断个位
第一题:
#include <iostream>
using namespace std;
bool test(int n)
{
for (int j = 0; j < 5; j++)
{
if ((n - 1)%5 != 0)
{
return false;
}
n = (n - 1)/5 * 4;
}
return true;
}
void main()
{
for (int i = 10; i < 10000; i++)
{
if(test(i))
cout << i << " ";
}
cout << endl;
}
return rand7() + ( rand7() - 1 ) / 2;
引用“xubo115”的评论:
第二题有人解决掉吗??
(7-rand7)/(7-1)*(10-1)+1这样应该可以
这是反求0到1随机数,再求1到10随机
已经有很多人出答案了啊,10个rand7()相加整除10啊。
引用“xubo115”的评论:
第二题有人解决掉吗??
回复eagleatustb:10个rand7相加,模10取余,能得到10个结果,每个结果都来自7种可能,但是怎么验证它们总的概率是相等的呢
第二题有人解决掉吗??
猴子分桃,这样行不?
- private void aa()
- {
- for ( int n = 1; n <= 1000000; n++)
- {
- if (a1(n))
- {
- MessageBox.Show(n.ToString());
- break ;
- }
-
- }
- }
- private bool a1( int n)
- {
-
- if ((n-1)%5==0)
- {
- n = ((n - 1) / 5) * 4;
- if ((n - 1) % 5 == 0)
- {
- n = ((n - 1) / 5) * 4;
- if ((n - 1) % 5 == 0)
- {
- n = ((n - 1) / 5) * 4;
- if ((n - 1) % 5 == 0)
- {
- n = ((n - 1) / 5) * 4;
- if ((n - 1) % 5 == 0)
- {
- n = ((n - 1) / 5) * 4;
- return true ;
- }
- }
- }
- }
- }
private void aa() { for (int n = 1; n <= 1000000; n++) { if (a1(n)) { MessageBox.Show(n.ToString()); break; } } } private bool a1(int n) { //第一次 if ((n-1)%5==0) { n = ((n - 1) / 5) * 4;//第一次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第二次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第三次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第四次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第五次结余数 return true; } } } } }
哈哈,这么难啊
第一题,我上次在看一个创新工厂的时候看过这个题,闲了的时候也看了看,最初用各种假设,不过后来觉得这tmd不就一道高中还是初中数学中学的那个求值嘛,然后用数学的方法解释一下:设剩下的鱼的条数为x条,一共有y条鱼得出以下:
5x/4+1)5/4+1)5/4+1)5/4+1)5/4+1=y
当x>=1时,即可求出y的值。
没有去算这个值是多少,如觉得此方法不妥,请求指导。
也是枚举啊。。。
引用“xubo115”的评论:
第一题:3121,代码如下,暂时木有参考其他人,继续下面的题
[code=java]
public ...
回复eagleatustb:题目一看,最快只能想到这个办法了,我正在看高手们的解答- -
回复eagleatustb:第二题你做出来没?
第一题:3121,代码如下,暂时木有参考其他人,继续下面的题
- public class peach {
- public static void main(String []args){
- int i,j;
- int n= 6 ;
- for (;;){
- i=n;
- for (j= 1 ;j<= 6 ;j++){
- if ((i- 1 )% 5 == 0 )
- i= (i- 1 )* 4 / 5 ;
- else break ;
- }
- if (j == 6 )
- break ;
- n=n+ 5 ;
- }
- System.out.println( "the min number is " +n);
- }
- }
public class peach { public static void main(String []args){ int i,j; int n=6; for(;;){ i=n; for(j=1;j<=6;j++){ if ((i-1)%5 == 0) i= (i-1)*4/5; else break; } if (j == 6) break; n=n+5; } System.out.println("the min number is "+n); } }
第三题:如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
题目没有说明单个字符串内有没有重复,两个串重复个数要不要一致,我现在按重复个数也需要一致处理。
时间复杂度:O(n); n为字符串长度,再次遍历128次是常数,少于O(n),忽略。
空间复杂度:O(1); 固定为128个桶排序原理需要的空间。其他临时变量忽略不计
- bool CItems::CheckBrotherString( char *left, char *right)
- {
-
- char keys[128];
- for ( int i = 0; i<128; i++ )
- {
- keys[i]=0;
- }
-
- while ( *left!= '\0' )
- {
- keys[*left++]++;
- }
-
- while ( *right!= '\0' )
- {
- keys[*right++]--;
- }
-
- for ( int i = 0; i<128; i++ )
- {
- if ( keys[i]!=0)
- {
- return false ;
- }
- }
- return true ;
- }
bool CItems::CheckBrotherString(char *left,char *right) { //把键盘128个字符列举,使用桶排序相关原理实现 char keys[128]; for ( int i = 0; i<128; i++ ) { keys[i]=0; } //遍历第一个字符串,记录字符个数 while ( *left!='\0' ) { keys[*left++]++; } //遍历第二个字符串,记录字符个数 while ( *right!='\0' ) { keys[*right++]--; } for ( int i = 0; i<128; i++ ) { if ( keys[i]!=0) { return false; } } return true; }
第一题题意考查的不是会不会枚举数字判断,是运筹学里的整数规划问题!大家要明确题目考查的知识点。使用好知识以后这题计算复杂度是O(n)(n是猴子数目),即使来10,1000个猴子,也一样能算;
注:数字溢出先不考虑
但如果用枚举法,算法复杂度?先不用逻辑判断,单单5->3121;粗略算了一下,起码是O(n^3)!
- case 2:
-
- switch ( m%4 )
- {
- case 1:
- k = 2;
- break ;
- case 2:
- k = 1;
- break ;
- case 3:
- printf( "ERROR!" );
- break ;
- default :
- printf( "ERROR!" );
- break ;
- }
- break ;
- case 3:
-
- switch ( m%4 )
- {
- case 1:
- k = 1;
- break ;
- case 2:
- printf( "ERROR!" );
- break ;
- case 3:
- k = 7;
- break ;
- default :
- printf( "ERROR!" );
- break ;
- }
- break ;
- default :
- break ;
- }
- return k;
- }
case 2: //m*k%4 need to equal 2 switch ( m%4 ) { case 1: k = 2; break; case 2: k = 1; break; case 3: printf("ERROR!"); break; default: printf("ERROR!"); break; } break; case 3: //m*k%4 need to equal 1 switch ( m%4 ) { case 1: k = 1; break; case 2: printf("ERROR!"); break; case 3: k = 7; break; default: printf("ERROR!"); break; } break; default: break; } return k; }
- int CItems::GetKValue( int y, int m)
- {
- int k=-1;
-
-
-
- switch ( y%4 )
- {
- case 0:
-
- switch ( m%4 )
- {
- case 1:
- case 3:
- k = 4;
- break ;
- case 2:
- k = 2;
- break ;
- default :
- printf( "ERROR!" );
- break ;
- }
- break ;
- case 1:
-
- switch ( m%4 )
- {
- case 1:
- k = 3;
- break ;
- case 2:
- printf( "ERROR!" );
- break ;
- case 3:
- k = 1;
- break ;
- default :
- printf( "ERROR!" );
- break ;
- }
- break ;
int CItems::GetKValue(int y,int m) { int k=-1; //let x = y+m*k; //search k st. x is integer //y%5=1;make (m*k)%4 = 3 switch ( y%4 ) { case 0: //m*k%4 need to equal 4 switch ( m%4 ) { case 1: case 3: k = 4; break; case 2: k = 2; break; default: printf("ERROR!"); break; } break; case 1: //(m*k)%4 need to equal 3 switch ( m%4 ) { case 1: k = 3; break; case 2: printf("ERROR!"); break; case 3: k = 1; break; default: printf("ERROR!"); break; } break;
第一题:五只猴子分桃。半夜,第一只猴子先起来,它把桃分成了相等的五堆,多出一只。于是,它吃掉了一个,拿走了一堆; 第二只猴子起来一看,只有四堆桃。于是把四堆合在一起,分成相等的五堆,又多出一个。于是,它也吃掉了一个,拿走了一堆;......其他几只猴子也都是 这样分的。问:这堆桃至少有多少个?(朋友说,这是小学奥数题)。
正确答案
- void CItems::MonkeyAndPeachs()
- {
-
-
-
-
-
- int y = 0;
-
- int m = 1;
- int k = 0;
- int i;
- for ( i =0;i<5;i++ )
- {
- if ( (k = GetKValue(y,m))<0 )
- {
- printf( "ERROR!" );
- return ;
- }
-
-
- y = (y+m*k)*5/4+1;
- m *=5;
- printf( ",%d:%d \n" ,i,y);
- }
-
- printf( "The result is %d" ,y);
- return ;
- }
void CItems::MonkeyAndPeachs() { //y0-1 = 5*y1/4; //y1-1 = 5*y2/4; //y2-1 = 5*y3/4; //y3-1 = 5*y4/4; //y4-1 = 5*y5/4; int y = 0; //int x = 0; int m = 1; int k = 0; int i; for ( i =0;i<5;i++ ) { if ( (k = GetKValue(y,m))<0 ) { printf("ERROR!"); return ; } //x = y+m*k; //y = x*5/4+1; y = (y+m*k)*5/4+1; m *=5; printf(",%d:%d \n",i,y); } printf("The result is %d",y); return ; }
mark 一下 抽时间研究一下
1只老鼠 可以最多判断2瓶毒药 2^1
2只最多判断 4瓶毒药 2^2
3只 8 2^3
1 喝 1357
2 喝 2356
3 喝 4567
如果1 死 2 3 活 则 第1瓶有毒 二进制 也就是 001
如果2 死 1 3 活 则 第2瓶有毒 二进制 也就是 010
如果1 2 死 3 活 则 第3瓶有毒 二进制 也就是 011
如果3 死 1 2 活 则 第4瓶有毒 二进制 也就是 100
如果1 3 死 2 活 则 第5瓶有毒 二进制 也就是 101
如果2 3 死 1 活 则 第6瓶有毒 二进制 也就是 110
如果1 2 3 全死 则 第7瓶有毒 二进制 也就是 111
如果1 2 3 全活 则 第8瓶有毒 二进制 也就是1000
所以5只老鼠可以测2的5次方也就是32瓶
回复ywch520:你是对的
好东东. 淘便宜 www.itaobb.com
淘宝打折网 www.xflian.com
rand10的问题,循环10次就够了,多了也没有用,少了概率分布不均匀。
int rand10() {
int value = 0;
for(int i = 0; i < 10; i++) {
value += rand7();
}
return value % 10;
}
第2题最简单,10个rand7()相加,除以7并取整应该就可以了。
回复tairikun01:估计不行,直接除的话有些数字覆盖不到的
回复tairikun01:玩骰子,扔到8点,跟扔到2,12点概率一样吗?想清楚在回答~
1,1概率是1/36,3,5,35,44,6,2,2,6,你自己对比概率多少吧
竟然能用程序啊,那就好办多了,我还在用笔算呢,浪费时间啊
桃子问题:
#include<iostream.h>
void main()
{
int peach_number; //存储分之前的桃子个数
int peach_number1; //存储第1只猴子操作后剩下的桃子个数
int peach_number2; //存储第2只猴子操作后剩下的桃子个数
int peach_number3; //存储第3只猴子操作后剩下的桃子个数
int peach_number4; //存储第4只猴子操作后剩下的桃子个数
for( peach_number=6;peach_number>=6;peach_number++)
{
if((peach_number-1)%5==0)
{
peach_number1=(peach_number-1)*4/5;
if((peach_number1-1)%5==0)
{
peach_number2=(peach_number1-1)*4/5;
if((peach_number2-1)%5==0)
{
peach_number3=(peach_number2-1)*4/5;
if((peach_number3-1)%5==0)
{
peach_number4=(peach_number3-1)*4/5;
if((peach_number4-1)%5==0) //第5只猴子操作后,满足要求就退出循环
break;
}
}
}
}
}
cout<<"桃子至少含有:"<<peach_number<<endl;
}
第二题:
int rand10()
{
int nResult=0;
while(true)
{
nResult=rand7();
if(nResult<=5)
break;
}
while(true)
{
int n = rand7();
if (n==1)
continue;
else if(n>4)
nResult*=2;
else
nResult=nResult*2-1;
break;
}
return nResult ;
}
我能想到的效率比较高、随机比较平均的算法,用加法和乘法的好像都有问题,因为数值分区间的概率是有问题的
13题:
无数瓶无色液体,只有一瓶是毒药
喝了无色液体,五分钟后才会看到结果。
现在五只老鼠,五分钟的时间,问能检测多少瓶液体
1、五只小白鼠分别喝了5瓶无色液体,五分钟过后,其中一只死亡,那么可以确定全部液体,只有一瓶毒药,那么就全部分开来。
2、分别喝了在5分钟后均未死亡,那么只能确定5瓶蒸馏水。
PS:给定的条件是五只老鼠,五分钟的时间,每只老鼠喝了毒药五分钟后才会死亡。
回复love_t:为何不考虑,把其中的2瓶或者三瓶或者4瓶等组合起来再给老鼠吃呢?
这样至少可以检查大于5瓶的个数。
至少可以检测8瓶。如果要检测到10瓶的,有一定的概率。
一下方法可以一次性检测10瓶。
把10瓶毒药分为4组,前三组各三瓶,最后1组1瓶。
只检测前面三组。
假定三个组分别为A,B,C。
1. 把A,B,C三组中的液体混合,分别给三只老鼠喝。
分别为测试用例 a,b,c
2. 分别从A,B,C组中各取1只液体,混合,给第四只老鼠吃。为测试用例 d
3.分别在从A,B,C组中各取一次液体(第二部取过的,不能在取),混合,给第五只老鼠吃。为测试用例e
这样,不过毒药在那瓶液体都可以在5分钟中一次性得到液体在拿一瓶。
如果 abcde都活着,说明毒药是那瓶没有参加测试的。
如果abcde只有一个死了,说明毒液在在吃参与混合测试一次的那瓶液体中。虽然有三瓶液体只混合了一次测试,但是从死的那只测试编号可以知道是那个组。
如果abcde死了2只,那么交叉也可以得出那瓶是毒液。
都是人才
猴子分桃的答案,能够连续5次(每次递增N)除4余数为0,并除5余1,除到第5次时,就是最终数了。
哈,桃子问题我答案算出来了,但是方法好复杂,看楼上的解答,恍然大悟,简洁明了,正是优秀算法的实现啊,什么时候我才能达到25楼的水平呢
大家总是爱说反话。。。回复wang_wen_feng:
-
- bool matchbrotherstr( char * str1, char * str2)
- {
- int s1[26] = {0}, s2[26] = {0};
- char *p;
- for (p = str1; *p != NULL;p++)
- s1[*p - 'a' ]++;
- for (p = str2; *p != NULL;p++)
- s2[*p - 'a' ]++;
- for ( int i = 0; i < 26; i++){
- if (s1[i] == s2[i])
- continue ;
- else
- return false ;
- }
- return true ;
- }
//需要事先知道字符集,假定为26个字母吧 bool matchbrotherstr(char* str1, char* str2) { int s1[26] = {0}, s2[26] = {0}; char *p; for(p = str1; *p != NULL;p++) s1[*p -'a']++; for(p = str2; *p != NULL;p++) s2[*p -'a']++; for(int i = 0; i < 26; i++){ if(s1[i] == s2[i]) continue; else return false; } return true; }
回复x313695373:这个方法和前面的7*(random7()-1) + random7() 方法都是概率均等的,但是都需要对随机数进行有效性判断,如果运气足够差,那么永远也返回不了,有没有更好的方法呢
这个应该是随机的,实在想不到更好的办法了,
其实这题挺难的,应为要实现真正的随机,我想大多数人一开始想的方法都不是随机分布的
- int rand7()
- {
- return rand()%7 + 1;
- }
- int rand10()
- {
- int tmp, mid;
- do {
- mid = rand7();
- } while (mid == 4);
-
- if (mid < 4){
- do {
- tmp = rand7();
- } while (tmp == 1 || tmp == 7);
- return tmp - 1;
- } else {
- do {
- tmp = rand7();
- } while (tmp == 1 || tmp == 7);
- return tmp + 4;
- }
- }
int rand7() { return rand()%7 + 1; } int rand10() { int tmp, mid; do{ mid = rand7(); }while(mid == 4); //50%概率 if(mid < 4){//return 1-5 do{ tmp = rand7(); }while(tmp == 1 || tmp == 7); return tmp - 1; }else{//return 6-10 do{ tmp = rand7(); }while(tmp == 1 || tmp == 7); return tmp + 4; } }
11题想了一个O(N^2)的算法(N为集合中的元素总数)
设有n个集合(集合用队列表示)
for(i =0; i < n;++i)
{
取出集合i中的一个元素x并依次和集合i+1到集合n-1比较,
如果x在后面的集合中,则后面的集合与当前集合合并。
合并后n减1.
}
第一题:答案为3121;
- int _tmain( int argc, _TCHAR* argv[])
- {
- int result = 0;
- while ( true ){
- int a[6];
- a[5] = result*4;
- int i;
- for (i = 4; i >=0; i--){
- if (a[i+1]%4 == 0){
- a[i] = a[i+1]*5/4 + 1;
- continue ;
- }
- break ;
- }
- if (i == -1){
- printf( "%d" , a[0]);
- break ;
- }
- else
- result++;
- }
-
- return 0;
- }
int _tmain(int argc, _TCHAR* argv[]) { int result = 0; while(true){ int a[6]; a[5] = result*4; int i; for(i = 4; i >=0; i--){ if(a[i+1]%4 == 0){ a[i] = a[i+1]*5/4 + 1; continue; } break; } if(i == -1){ printf("%d", a[0]); break; } else result++; } return 0; }
第二题:
function rand10()
{
int a = rand7();
int b = rand7();
int c = rand7();
int m = a+b+c;//值是3到21
int n = m-1;//值是2到20
return n/2;
}
回复bsglz:刚开始觉得挺好的,后来……
3=1+1+1
4=1+1+2=1+2+1=2+1+1 4的概率是3的概率的三倍
5=1+1+3=……
目前觉得
引用“wwq3073135”的评论: 2、while(1){
x=7*(random7()-1) + random7() ;
if(x...[/quote]
的方法比较好
解释见
[quote=chaoyue1216]明白了,确实是 7*(random7()-1) + random7() 生成的数在1到49间均匀分面...
搞这么难得题目,不知道给开多少工资?哥还是悠着点
第六题:淘宝面试题:有一个一亿节点的树,现在已知两个点,找这两个点的共同的祖先。
题目没有说明是使用什么方式存储什么样的树,我只以最简单的完全二叉树的方式去计算。
如果不是二叉树又另当别论
-
-
- int x =10;
- int y =100;
- while (1)
- {
- if (x==y)
- {
- break ;
- }
- x>y?x/=2:y/=2;
- }
- printf( "The parent is %d" ,x);
//如果二叉树使用数组顺序存储结构,第一个节点下标是x,第二个节点下标是y; //第0个节点不使用,1为根节点,算法如下 int x =10; int y =100; while(1) { if (x==y) { break; } x>y?x/=2:y/=2; } printf("The parent is %d",x);
第五题:
- int Array[10] = { -1,2,-3,4,-5,6,-7,8,-9,10 };
- int index_front = 0;
- int temp;
- int i;
- int j;
- for ( i = 0; i<10; i++ )
- {
- if (Array[i]<0)
- {
- temp = Array[i];
- for ( j = i;j>index_front; j--)
- {
- Array[j] = Array[j-1];
- }
- Array[index_front] = temp;
- index_front++;
- }
- }
- for ( i = 0; i<10; i++ )
- {
- printf( ", %d" ,Array[i]);
- }
int Array[10] = { -1,2,-3,4,-5,6,-7,8,-9,10 }; int index_front = 0; int temp; int i; int j; for ( i = 0; i<10; i++ ) { if (Array[i]<0) { temp = Array[i]; for ( j = i;j>index_front; j--) { Array[j] = Array[j-1]; } Array[index_front] = temp; index_front++; } } for ( i = 0; i<10; i++ ) { printf(", %d",Array[i]); }
回复eagleatustb:时间复杂度是O(N)
回复eagleatustb:你这个算法不是O(N)吧?
第一题
const int monkey = 5;
bool text_last_take(int n)
{
for(int i = 0 ; i < monkey - 1 ; i ++)
{
if((n*5+1)%4 == 0)
{
n =(n*5+1)/4;
continue;
}
return false;
}
return true;
}
int total(void)
{
int last_get = 0 ;
while(! text_last_take(++last_get))
{
if(last_get>1000) return 0;
}
printf("%d\n",last_get);
for(int i = 0 ; i < monkey-1;i++)
{
last_get = (last_get*5+1)/4;
}
return last_get*5+1;
}
int main(int argc, char* argv[])
{
printf("%d\n",total());
return 0;
}
不知道是不是,我是枚举出最后一个猴子拿走的的那一份个数然后回溯上去,最后猴子拿走255个,桃子总是是3121,请高人指点下。
还有楼主,你blog流量高我们都知道
第三题,可以按字母的顺序搞个数组统计.
第四题,应该就是用hash表或者树
第一题和第十二题不是非常相似,实际上就是n的m次方减(n-1)
n是分的堆数,m是分的次数.
int rand10()
{
return rand7() * rand7() %11
}