1:顺序表(有序)二路归并找成绩排名
总时间限制: 100000ms 内存限制: 10240kB
描述
学生成绩表A、B分别存储有n和m个学生的成绩(int整数),A、B中所有成绩分别以递减有序顺序表的方式存储,假设这n+m个成绩各不相同。利用二路归并的思路设计一个算法求这n+m个成绩中排名第k(k从1开始编号)的学生,输出其成绩。
输入
排名k
输出
排名k 成绩
或
k=排名k err
样例输入
2
样例输出
2 92
ac代码:
#include <stdio.h>
#define MAXSIZE 255
typedef int ElemType;
typedef struct
{ ElemType stu_score[MAXSIZE];
int length;
} StuSqList;
void InitList(StuSqList &L)
{
L.length=0;
}
void DestroyList(StuSqList L)
{
}
void CreateList(StuSqList &L,ElemType a[],int n)
{
int i,k=0;
for (i=0;i<n;i++)
{
L.stu_score[k]=a[i];
k++;
}
L.length=k;
}
int Topk(StuSqList A,StuSqList B,int k,ElemType &e)
{
int i=0,j=0,p=0;
while(i<A.length&&j<B.length)
{
if(p==k)
{
return e;
}
else if(A.stu_score[i]>B.stu_score[j])
{
e=A.stu_score[i];
i++;
p++;
}
else if(A.stu_score[i]<B.stu_score[j])
{
e=B.stu_score[j];
j++;
p++;
}
}
while(i<A.length&&p<k)
{
e=A.stu_score[i];
i++;
p++;
}
while(j<B.length&&p<k)
{
e=B.stu_score[j];
j++;
p++;
}
if(p==k)
{
return e;
}
else
{
return 0;
}
}
int main()
{
StuSqList L1,L2;
ElemType a[]={98,86,85,78,75,72,69,62,52};
int n=sizeof(a)/sizeof(a[0]);
CreateList(L1,a,n);
ElemType b[]={92,90,82,81,79,77,73,64,63};
int m=sizeof(b)/sizeof(b[0]);
CreateList(L2,b,m);
ElemType e;
int k;
scanf("%d",&k);
if (Topk(L1,L2,k,e))
printf("%d %d",k,e);
else
printf("k=%d err",k);
DestroyList(L1);
DestroyList(L2);
}
变式:二路归并算法
已知A、B是两个递增有序顺序表,现想将他们归并为一个递增有序顺序表C
void Merge(Sqlist A,Sqlist B,Sqlist &C)
{
int i=0,j=0,k=0;
while(i<A.length && j<B.length)
{
if(A.data[i]<B.data[j])
{
C.data[k]=A.data[i];
i++;
k++;
}
else
{
C.data[k]=B.data[j];
j++;
k++;
}
}
while(i<A.length)
{
C.data[k]=A.data[i];
i++;
k++;
}
while(j<B.length)
{
C.data[k]=B.data[j];
j++;
k++;
}
C.length=k;
}
本算法空间复杂度为o(1),时间复杂度为o(m+n),其中m和n分别为A和B两顺序表的长度。
2:求解约瑟夫问题
总时间限制: 1000ms 内存限制: 65536kB
描述
编写一个程序求解约瑟夫(Joseph)问题。有n个小孩围成一圈,给他们从1开始依次编号,从编号为1的小孩开始报数,数到第5个小孩出列,然后从出列的下一个小孩重新开始报数,数到第5个小孩又出列,…,如此反复直到所有的小孩全部出列为止,求最后出列的小朋友的编号。
输入
小朋友总人数
输出
最后出列的竞争者的编号
样例输入
90
样例输出
88
ac代码:
#include <malloc.h>
#include <iostream>
using namespace std;
typedef struct node
{
int no; //小孩编号
struct node *next; //指向下一个结点指针
} Child;
void CreateList(Child *&L, int n) //建立有n个结点的循环单链表
{
int i; Child *p, *tc; //tc指向新建循环单链表的尾结点
L = (Child *)malloc(sizeof(Child));
L->no = 1; //先建立只有一个no为1结点的单链表
tc = L;
for (i = 2; i <= n; i++)
{
p = (Child *)malloc(sizeof(Child));
p->no = i; //建立一个存放编号i的结点
tc->next = p; tc = p; //将p结点链到末尾
}
tc->next = L; //构成一个首结点为L的循环单链表
}
void Joseph(int n) //求解约瑟夫序列
{
int i, j; Child *L, *p, *q;
CreateList(L, n);
int m = 5;
for(i=1;i<=n;i++)
{
p=L;j=1;
while(j<4)
{
j++;
p=p->next;
}
q=p->next;
if(i==n)
{
printf("%d ",q->no);
}//若想依次输出,只需去掉if条件
p->next=q->next;
free(q);
L=p->next;
}
}
int main()
{
int n;
cin>> n;
Joseph(n);
system("pause");
return 0;
}
3:单链表-删除值重复节点
总时间限制: 10000ms 内存限制: 10000kB
描述
有一个非空整数单链表L,设计一个算法删除值重复的节点,多个值相同的节点仅保留第一个。
输入
8
1 4 1 2 2 1 3 4
输出
1 4 2 3
样例输入
8
1 4 1 2 2 1 3 4
样例输出
1 4 2 3
不知道为什么写了好多种方法都是dev能过,oj过不了,现把oj上ac的代码贴在这里
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int Elemtype;
typedef struct LNode{
Elemtype data;
struct LNode *next;
}LNode,*Linklist;
void Init_Linklist(Linklist *L)
{
*L=(Linklist)malloc(sizeof(LNode));
assert(*L != NULL);
(*L)->next=NULL;
}
void Create_Linklist(Linklist *L)
{
int n;
LNode *p,*q;
p = *L;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
q=(Linklist)malloc(sizeof(LNode));
assert( q != NULL);
scanf("%d",&q->data);
p->next=q;
p=q;
}
p->next=NULL;
}
void delsame(Linklist *L)
{
LNode *p,*q,*s;
p = (*L)->next;
for(p;p!=NULL;p=p->next)
{
s=p;
for(q=p->next;q!=NULL; )
{
if(q->data==p->data)
{
s->next=q->next;
free(q);
q=s->next;
}
else
{
s=q;
q=q->next;
}
}
}
}
void Print_Linklist(Linklist *L)
{
LNode *p;
p = *L;
while(p->next)
{
p=p->next;
printf("%d ",p->data);
}
printf("\n");
}
int main()
{
Linklist L;
Init_Linklist(&L);
Create_Linklist(&L);
delsame(&L);
Print_Linklist(&L);
return 0;
}
再附上一个我看不出哪错了的写法,以后也许会发现问题所在。
#include<iostream>
#include<cstdlib>
using namespace std;
const int MAXSIZE=100;
#define ElemType char
typedef struct LNode{
ElemType data;
struct LNode *next;
}LinkNode;
bool InitList(LinkNode *&L)
{
L=(LinkNode *)malloc(sizeof(LinkNode));
if(!L)
return false;
L->next=NULL;
}
void CreateListF(LinkNode *&L,ElemType a[],int n)//头插法
{
LinkNode *s;
int i;
L=(LinkNode *)malloc(sizeof(LinkNode));
L->next=NULL;
for(i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=a[i];
s->next=L->next;
L->next=s;
}
}
void CreateListR(LinkNode *&L,ElemType a[],int n)//尾插法
{
LinkNode *s,*r;
int i;
L=(LinkNode *)malloc(sizeof(LinkNode));
r=L;
for(i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=a[i];
r->next=s;
r=s;
}
r->next=NULL;
}
void DispList(LinkNode *&L)
{
LinkNode *p=L->next;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int GetLength(LinkNode *L)
{
int i=0;
LinkNode *p=L->next;
while(p!=NULL)
{
i++;
p=p->next;
}
return i;
}
bool GetElem(LinkNode *&L,int i,ElemType &e)
{
int j=0;
LinkNode *p=L;
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
return false;
else{
e=p->data;
return true;
}
}
int LocateElem(LinkNode *&L,ElemType e)
{
int i=1;
LinkNode *p=L->next;
while(p!=NULL&&p->data!=e)
{
p=p->next;
i++;
}
if(p==NULL)
return (0);
else
return (i);
}
bool ListEmpty(LinkNode *L)
{
return(L->next==NULL);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
int j=0;
LinkNode *p=L,*s;
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
return false;
else{
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
int j=0;
LinkNode *p=L,*q;
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
return false;
else
{
q=p->next;
if(q==NULL)
return false;
e=q->data;
p->next=q->next;
free(q);
return true;
}
}
void DestoryList(LinkNode *&L)
{
LinkNode *pre=L,*p=L->next;
while(p!=NULL)
{
free(pre);
pre=p;
p=pre->next;
}
free(pre);
}
int delsame(LinkNode *&L)
{
LinkNode *p,*q,*s;
p=L->next;
while(p!=NULL && p->next!=NULL)
{
s=p;
q=p->next;
while (q!=NULL)
{
if (q->data==p->data)
{
s->next=q->next;
free(q);
q=s->next;
}
else
{
s=q;
q=q->next;
}
}
p=p->next;
}
}
int main()
{
LinkNode *L;
ElemType e;
InitList(L);
int n;
char a[MAXSIZE];
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
CreateListR(L,a,n);
delsame(L);
DispList(L);
DestoryList(L);
}
问了一个同学,他说把delsame函数用void更好,不过也不能上oj测了,不知道改完能不能过orz