【1】分红包问题。将总金额m随机分到n个钱包中。保证每个钱包的金额在1-100之间。
这道题目的考查的方面:
(1)判断初始条件是否满足,当总金额过大(>100*n,钱发不完)或者过小(<n,钱不够发)时,抛出异常;
(2)每次随机数应该满足的条件
- 去掉该金额后,必须保证余下的红包每个至少有1元钱;
- 去掉该金额后,余下的总数应该不大于让每个红包都装满100元的总额;
- 规定的条件:必须位于1-100之间(包括1和100)
所以该金额应该位于max(1,total-(n-i-1)) -- min(100,total-(n-i-1)*100)之间。
这个算法的问题在于:刚开始分配时,产生随机数的范围比较大,所以会导致前面的红包含的金额明显比较大,而后面的红包金额偏小,会出现大量的只有1元钱的红包。最后采用了一个混洗(shuffle)的算法,打乱次序,但是总体来讲,产生的数组的方差很大。
如果要产生的数组之间的差距不大,那么应该加上约束条件或者采用其他的方法。
方法一:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;
void hongbao(int m,int n,int *p)
{
int total = m;
if(m < n)
{
cout << "No enough money for everyone" << endl;
exit(-1);
}
if(m > 100 * n)
{
cout << "Too much money" << endl;
exit(-1);
}
srand((int)time(NULL));
for(int i = 0; i < n; i++)
{
int minnumber = max(1,total - (n - i - 1) * 100);
int maxnumber = min(100,total - (n - i - 1));
/* a number between minnumber and maxnumber */
if(maxnumber == minnumber)
p[i] = maxnumber;
else
p[i] = rand() % (maxnumber - minnumber + 1) + minnumber; //产生minnumber-maxnumber之间的一个数
total -= p[i];
}
for(int i = 0; i < n; i++)
{
int index = rand() % n;
// swap p[i] and p[index]
int temp = p[i];
p[i] = p[index];
p[index] = temp;
}
}
int main()
{
int m,n;
while(1)
{
cin >> m >> n;
int *p = (int *)malloc(sizeof(int) * n);
hongbao(m,n,p);
for(int i = 0; i < n; i++)
cout << p[i] << ' ';
cout << endl;
}
}
方法二:
- 首先排除异常情况,钱太多或者钱太少的情况;
- 然后分给每个人1元钱
- 利用随机数产生下标0-n-1,并给这个红包1元钱(当该红包的钱数等于100时,重新分配)
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;
void hongbao(int m,int n,int *p)
{
if(m < n)
{
cout << "No enough money for everyone" << endl;
exit(-1);
}
if(m > 100 * n)
{
cout << "Too much money" << endl;
exit(-1);
}
//初始化
for(int i=0; i < n;i++)
p[i] = 1;
for(int i=0; i < m - n; i++)
{
int index = rand() % n;
if(p[index] < 100)
p[index]++;
else
i--;
}
}
int main()
{
int m,n;
while(1)
{
cin >> m >> n;
int *p = (int *)malloc(sizeof(int) * n);
hongbao(m,n,p);
for(int i = 0; i < n; i++)
cout << p[i] << ' ';
cout << endl;
}
}
【2】字符串滤除问题。设有两个只包含英文字符的字符串s1和s2,将在s2中出现的字符从s1中去掉。函数原型:string filter(string s1,string s2)。
这道题比较基础。采用一个字符数组映射s2中出现的字符,即可解决,算法复杂度为O(n)。
#include <iostream>
#include <string>
using namespace std;
// 去掉s1中在s2中出现的字符
string filter(string s1,string s2)
{
int charsequence[52] = {0};
string s3;
for(unsigned i = 0; i < s2.length(); i++)
{
charsequence[s2[i] - 'a'] = 1;
}
for(unsigned i = 0; i < s1.length(); i++)
{
if(charsequence[s1[i]-'a'] != 1)
s3.append(s1.substr(i,1));
}
return s3;
}
int main()
{
string s1,s2,out;
cin >> s1 >> s2;
out = filter(s1,s2);
cout << out << endl;
}
【3】设计一个用数组实现的堆栈,并能够动态调整存储空间。当栈满时,空间扩充为原来的两倍。当元素的个数不足空间的1/4时,空间自动减少为原来的1/2。
基础题目:估计主要是考察动态存储吧。。。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
class MyStack
{
private:
int *stack;
int capacity;
int size;
public:
MyStack()
{
capacity = 1;
size = 0;
stack = (int *)malloc(sizeof(int) * capacity);
}
MyStack(int cap)
{
this->capacity = cap;
size = 0;
stack = (int *)malloc(sizeof(int) * capacity);
}
void push(int number)
{
stack[size++] = number;
checkstack();
}
void pop()
{
if(size == 0)
{
cout << "No element to pop up" << endl;
return;
}
size --;
checkstack();
}
void checkstack()
{
if(size == capacity)
{
capacity *= 2;
stack = (int *)realloc(stack,sizeof(int) * capacity);
}
if( size < capacity / 4 && capacity >= 1)
{
capacity /= 2;
stack = (int *)realloc(stack,sizeof(int) * capacity);
}
}
void printCap()
{
cout << capacity << " " << size << endl;
}
};
int main()
{
MyStack stack1(100);
int i = 20;
while(i-- > 0){
stack1.push(i);
stack1.printCap();
}
while(i++ < 25)
{
stack1.pop();
stack1.printCap();
}
return 0;
}