题目:
从以下六个题目中选择四个题目,每个题目25分,共100分。请在选作的题目前面打上√并按照示例对每个题目做出解答。
No Copying
一、表达式求值问题
二、看病排队候诊问题
三、计算哈夫曼树的WPL值
四、图的应用
五、哈希表的应用
六、汽车牌照的快速查询
给定一个四则运算的中缀表达式、前缀表达式和后缀表达式,编程计算表达式的值。 基本要求:
(1)在给定的表达式中要包含括号;
(2)栈的操作要求自己完成,不允许调用类库中的方法;
(3)对不同的操作编写相应的函数。 测试数据要求:
给定测表达式(字符串)中的数字字符要有包含两位以上的数字字符。
前缀
///前缀 author : revolIA
#include
using namespace std;
typedef long long ll;
struct Stack{
double *base;
int Top,len;
void init(){
base = (double*)malloc(sizeof(double));
len = 1,Top = 0;
}
void push(double x){
if(Top == len){
len <<= 1;
base = (double*)realloc(base,len*sizeof(double));
}
base[Top++] = x;
}
void pop(){
if(Top)
Top--;
}
double Gettop(){
return base[Top-1];
}
bool empty(){
return Top==0?1:0;
}
}st;
char s[10000];
double calculator(char s[]){
st.init();
int len = strlen(s);
int i = len-1;
while(~i){
if(s[i] == ' ')
i--;
else if(isdigit(s[i])){
ll ans = 0;
int Stack[10],x = 0;
while(i+1&&isdigit(s[i]))
Stack[x++] = s[i--]-'0';
while(x--)
ans = ans*10 + Stack[x];
st.push(1.0*ans);
}else{
double ans;
double a = st.Gettop();
st.pop();
double b = st.Gettop();
st.pop();
switch (s[i]){
case '+' : ans = a+b ;break;
case '-' : ans = a-b ;break;
case '*' : ans = a*b ;break;
case '/' : ans = a/b ;
}
st.push(ans);
i--;
}
}
return st.Gettop();
}
void Getline(char s[]){
int i = 0;
while((s[i]=getchar())!='\n')i++;
s[i]='\0';
}
int main(){
Getline(s);
//puts(s);
printf("%f\n",calculator(s));
return 0;
}
中缀
#include
using namespace std;
typedef long long ll;
union type{double a;char b;};
type make_type(char c){
type x;x.b = c;
return x;
}
type make_type(double c){
type x;x.a = c;
return x;
}
struct Stack{
type *base;
int Top,len;
void init(){
base = (type*)malloc(sizeof(type));
len = 1,Top = 0;
}
void push(type x){
if(Top == len){
len <<= 1;
base = (type*)realloc(base,len*sizeof(type));
}
base[Top++] = x;
}
void pop(){
if(Top)
Top--;
}
type Gettop(){
return base[Top-1];
}
bool empty(){
return Top==0?1:0;
}
}stn,stc;
int Getpriority(char s){
if(s == '(')return 1;
if(s == '+' || s == '-')return 2;
if(s == '*' || s == '/')return 3;
return 4;
}
void cal(Stack &stn,type x){
type ans;
double b = stn.Gettop().a;stn.pop();
double a = stn.Gettop().a;stn.pop();
switch (x.b){
case '+' : ans.a = a+b ;break;
case '-' : ans.a = a-b ;break;
case '*' : ans.a = a*b ;break;
case '/' : ans.a = a/b ;
}
stn.push(ans);
}
char s[10000];
double calculator(char s[]){
stn.init(),stc.init();
int len = strlen(s);
int i = 0;
while(len-i){
if(isdigit(s[i])){
ll ans = 0;
while(len-i && isdigit(s[i]))
ans = ans*10 + s[i++] - '0';
stn.push(make_type(1.0*ans));
i--;
}else if(Getpriority(s[i])==2 || Getpriority(s[i])==3){
if(stc.empty())
stc.push(make_type(s[i]));
else{
while(!stc.empty() && Getpriority(stc.Gettop().b) >= Getpriority(s[i])){
cal(stn,stc.Gettop());
stc.pop();
}
stc.push(make_type(s[i]));
}
}else{
if(s[i] == '(')
stc.push(make_type(s[i]));
else{
while(stc.Gettop().b != '('){
cal(stn,stc.Gettop());
stc.pop();
}
stc.pop();
}
}
i++;
}
while(!stc.empty()){
cal(stn,stc.Gettop());
stc.pop();
}
return stn.Gettop().a;
}
void Getline(char s[]){
int i = 0;
while((s[i]=getchar())!='\n')i++;
s[i]='\0';
}
int main(){
Getline(s);
//puts(s);
printf("%f\n",calculator(s));
return 0;
}
后缀
#include
using namespace std;
typedef long long ll;
struct Stack{
double *base;
int Top,len;
void init(){
base = (double*)malloc(sizeof(double));
len = 1,Top = 0;
}
void push(double x){
if(Top == len){
len <<= 1;
base = (double*)realloc(base,len*sizeof(double));
}
base[Top++] = x;
}
void pop(){
if(Top)
Top--;
}
double Gettop(){
return base[Top-1];
}
bool empty(){
return Top==0?1:0;
}
}st;
char s[10000];
double calculator(char s[]){
st.init();
int len = strlen(s);
int i = 0;
while(len-i){
if(s[i] == ' ')
i++;
else if(isdigit(s[i])){
ll ans = 0;
while(len-i&&isdigit(s[i]))
ans = ans*10 + s[i++]-'0';
st.push(1.0*ans);
}else{
double ans;
double b = st.Gettop();
st.pop();
double a = st.Gettop();
st.pop();
switch (s[i]){
case '+' : ans = a+b ;break;
case '-' : ans = a-b ;break;
case '*' : ans = a*b ;break;
case '/' : ans = a/b ;
}
st.push(ans);
i++;
}
}
return st.Gettop();
}
void Getline(char s[]){
int i = 0;
while((s[i]=getchar())!='\n')i++;
s[i]='\0';
}
int main(){
Getline(s);
//puts(s);
printf("%f\n",calculator(s));
return 0;
}
医院各科室的医生有限,病人到医院看病时必须排队就诊,而病人病情有轻重之分,不能简单地根据先来先服务的原则进行诊断治疗,所以医院根据病人的病情规定了不同的优先级别。医生在诊断治疗时,总是选择优先级别高的病人进行诊治,如果遇到两个优先级别相同的病人,则选择优先来排队的病人进行诊治。 基本要求:
(1)用队列模拟上述病人看病排队候诊问题;
(2)两个队列分别对应不同的优先级别,优先级高的队列中的病人优先就诊;
(3)按照从终端读入数的方式进行模拟管理。
测试数据要求:
病人信息包括:挂号编号、病历号、看病的优先级、姓名和性别。
#include
using namespace std;
typedef long long ll;
struct node{
ll regis_num,case_num;///挂号,病历
char name[40];
char sex[20];
int priority;
};
struct qnode{
node x;
qnode *nex;
};
struct Queue{
qnode *head,*tail;
void init(){
tail = head = (qnode*)malloc(sizeof(qnode));
head->nex = NULL;
}
void push(node a){
qnode *p = (qnode*)malloc(sizeof(qnode));
p->x = a;
p->nex = NULL;
tail->nex = p;
tail = tail->nex;
}
void pop(){
qnode *s = head->nex;
if(s == NULL)
return;
head->nex = s->nex;
free(s);
}
node front(){
return head->nex->x;
}
bool empty(){
return head->nex==NULL;
}
}Q[2];
void init(){
for(int i=0;i<2;i++)Q[i].init();
}
void input(){
node t;
int n;
printf("input the number of the patient\n");
scanf("%d",&n);
printf("regis_num case_num priority name sex\n");
while(n--){
scanf("%lld%lld%d%s%s",&t.regis_num,&t.case_num,&t.priority,t.name,t.sex);
Q[t.priority].push(t);
}
}
void output(){
printf("regis_num case_num priority name sex\n");
int k = 2;
while(k--){
while(!Q[k].empty()){
printf("%06lld %06lld %d %s %s\n",
Q[k].front().regis_num,Q[k].front().case_num,
Q[k].front().priority,Q[k].front().name,Q[k].front().sex),Q[k].pop();
}
}
}
int main(){
init();
input();
output();
return 0;
}/*
5
000001 000012 0 张三 男
000002 000016 0 李四 男
000003 000018 1 王五 男
000004 000019 1 钱六 男
000005 000033 0 赵八 男
*/
根据给定的n个权值(非负值),计算所构造哈夫曼树的WPL值。 基本要求:
(1)根据给定的数据,建立哈夫曼树;
(2)输出每个叶子结点的带权路径长度;
(3)输出哈夫曼树的WPL值。
测试数据要求:
输入的n个权值之和应为100,且不允许有负值。
#include
using namespace std;
typedef long long ll;
int n;
struct node{
int cnt;
node *l,*r;
void init(){
l = r = NULL;
}
};
struct cnode{
node *x;
cnode *nex;
};
struct QuQ{
cnode head;
int Cnt;
void init(){
Cnt = 0;
head.x = (node*)malloc(sizeof(node));
head.x->cnt = -1;
head.nex = NULL;
}
void push(node *x){
++Cnt;
cnode *p = (cnode*)malloc(sizeof(cnode)),*s = &head;
p->x = x;
p->nex = NULL;
if(!head.nex){
head.nex = p;
return;
}
while(s->nex&&s->nex->x->cnt<=x->cnt)
s = s->nex;
if(!s->nex)
s->nex = p;
else{
p->nex = s->nex;
s->nex = p;
}
}
node* pop(){
if(!head.nex)
return NULL;
--Cnt;
cnode* s = head.nex;
head.nex = s->nex;
node* ans = s->x;
free(s);
return ans;
}
}quq;
node* Create(){
quq.init();
printf("the number \n");
scanf("%d",&n);
for(int i=0;iinit();
scanf("%d",&x->cnt);
quq.push(x);
}
while(quq.Cnt>1){
node *t1,*t2,*t3 = (node*)malloc(sizeof(node));
t1 = quq.pop(),t2 = quq.pop();
t3->cnt = t1->cnt+t2->cnt;
t3->l = t1,t3->r = t2;
quq.push(t3);
}
return quq.pop();
}
int dfs(node* x,int i){
if(!x->l&&!x->r){
printf("%d\n",i*x->cnt);
return i*x->cnt;
}
int ans = 0;
if(x->l)
ans += dfs(x->l,i+1);
if(x->r)
ans += dfs(x->r,i+1);
return ans;
}
int main(){
node* tree = Create();
printf("WPL:%d\n",dfs(tree,0));
return 0;
}/*
3
20 30 50
4
30 24 26 20
*/
学校要建立一个娱乐中心,设计该娱乐中心的位置,使得各部门到中心的距离较近。
基本要求:
(1)顶点表示各部门,顶点之间连线上的权值表示两个部门的距离;
(2)采用邻接表存储图;
(3)采用Flody算法求最短路径;
(4)输出各路径及其距离。
测试数据要求: 输入表示权值的整数必须是正整数。
#include
using namespace std;
typedef long long ll;
const int maxn = 1e3+7;
int head[maxn],cnt,n,m;
int ans[maxn][maxn],pre[maxn][maxn];
struct node{
int to,val,nex;
}E[maxn*maxn];
void init(){
memset(head,-1,sizeof(head));
memset(pre,-1,sizeof(pre));
for(int i=0;iE[j].val)
ans[i][E[j].to]=E[j].val;
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(ans[i][j]>ans[i][k]+ans[k][j])
ans[i][j] = ans[i][k]+ans[k][j],pre[i][j] = k;
}
}
}
}
void dfs(int i,int j){
if(pre[i][j]==-1)
return;
dfs(i,pre[i][j]);
printf("->%d",pre[i][j]);
dfs(pre[i][j],j);
}
void input(){
init();
printf("the number of point\n");
scanf("%d",&n);
printf("the number of edge \n");
scanf("%d",&m);
printf("the two point and the value:\n");
int u,v,w;
for(int i=0;itans){
dis = tans;
ansi = i;
}
}
printf("the Recreation Center should be create in the %d-th point\n",ansi);
for(int i=1;i<=n;i++){
for(int j=1+i;j<=n;j++){
printf("from %d-th to %d-th :\nWeight:",i,j);
if(ans[i][j]==0x3f3f3f3f)
printf("%4d\n",-1);
else{
printf("%4d\n",ans[i][j]);
printf("path: %d",i);
dfs(i,j);
printf("->%d\n",j);
}
}
}
}
int main(){
init();
input();
floyd();
output();
return 0;
}/*
3
3
1 2 5
2 3 6
3 1 5
4
4
1 2 5
2 3 6
3 4 7
2 4 1
*/
根据给定的一组整数,建立哈希表。 基本要求:
(1)设计哈希函数;
(2)分别采用线性探测再散列法和链地址法解决冲突;
(3)对哈希表进行查找,输出查找成功和不成功的信息。
测试数据要求: 建立哈希表时输入的数据可以有相同的值。
线性探测再散列法
#include
using namespace std;
typedef long long ll;
const int len = 30,k = 3,b = 5;
int p[len],vis[len];
int Hash(int x){
return (3*x*x+b)%len;
}
void Push(int x){
int pos = Hash(x);
if(vis[pos]){
if(p[pos] == x)
return;
while(vis[pos]){
pos = (pos+1)%len;
}
}
printf("pos ( %02d ) : %02d\n",x,pos);
vis[pos] = 1;
p[pos] = x;
}
void Find(int x){
int pos = Hash(x);
if(p[pos]!=x){
int tp = (pos-1+len)%len;
while(pos!=tp && p[pos]!=x){
pos = (pos+1)%len;
}
}
printf("%s\n",(vis[pos] && p[pos]==x)?"Yes":"No");
}
int main(){
int a[5] = {1,2,6,4,10};
for(int i=0;i<5;i++){
printf("hash( %02d ) : %02d --> ",a[i],Hash(a[i]));
Push(a[i]);
}
for(int i=0;i<=10;i++)
printf("Find %3d: ",i),Find(i);
return 0;
}
链地址法
#include
using namespace std;
typedef long long ll;
const int len = 30,k = 3,b = 5;
int p[len],vis[len];
int cnt,head[len];
struct node{
int val,nex;
}edg[len];
void init(){
memset(head,-1,sizeof(head));
}
int Hash(int x){
return (3*x*x+b)%len;
}
void Push(int x){
int pos = Hash(x);
if(vis[pos]){
edg[cnt] = {x,head[pos]};
head[pos] = cnt++;
return;
}
vis[pos] = 1;
p[pos] = x;
}
void Find(int x){
int pos = Hash(x);
if(!vis[pos]){
printf("No\n");
return;
}
if(p[pos] == x){
printf("Yes\n");
return;
}
else{
for(int e = head[pos];~e;e = edg[e].nex){
if(edg[e].val == x){
printf("Yes\n");
return ;
}
}
}
printf("No\n");
}
int main(){
init();
int a[5] = {1,2,4,6,10};
for(int i=0;i<5;i++){
printf("hash( %02d ) : %02d \n",a[i],Hash(a[i]));
Push(a[i]);
}
for(int i=0;i<=10;i++)
printf("Find %2d: ",i),Find(i);
return 0;
}
对一组汽车牌照进行排序和查找。 基本要求:
(1)利用排序算法对汽车牌照进行排序;
(2)采用折半查找思想完成查找。
测试数据要求:
测试的数据不得少于50个,不得有重复的牌照。
车牌号中可以是数字和字符的组合,车牌号可以人工输入,也可以自动生成。
#include
using namespace std;
const int k = 60;
struct node{
char name[300];
}car[100];
void lower_bound_Find(node car[],int n,char p[]){
int l = 0,r = n-1,mid,sul = 0;
while(l<=r){
mid = (l+r)/2;
if(strcmp(car[mid].name,p)<=0)
l = mid+1,sul = mid;
else
r = mid-1;
}
if(strcmp(car[sul].name,p)==0)
printf("%-3d-th is %s\n",sul+1,p);
else
printf("Can not find %s\n",p);
}
void Ram(){
for(int i=0;i0){
char s[100];
strcpy(s,car[i].name);
strcpy(car[i].name,car[i+gap].name);
strcpy(car[i+gap].name,s);
}
gap/=1.3;
}
gap = 1;
while(gap){
gap = 0;
for(int i=0;i0){
char s[100];
strcpy(s,car[i].name);
strcpy(car[i].name,car[i+1].name);
strcpy(car[i+1].name,s);
gap++;
}
}
}
int main(){
srand(time(0));
Ram();
out();
combsort(car,k);
out();
char s[100];
while(1){
printf("\n\tinput the array \n");
scanf("%s",s);
lower_bound_Find(car,k,s);
}
return 0;
}