为了考试罢了。
7-1 求素数个数 (30分)
求素数的个数。本题要求编写一个程序,求1~n的素数个数。 要求至少给出两种解法,对于相同的n,给出这两种解法的结果,通过相关数据进行测试,目的是通过对比同一问题不同解法的绝对执行时间体会如何设计“好”的算法。
输入格式:
输入在一行中给出1个整数n(<= 10 000 000)。
输出格式:
对每一组输入,在一行中输出1~n的素数个数。
输入样例1:
5
输出样例1:
3
输入样例2:
14
输出样例2:
6
AC代码
如果有测试点运行超时,建议多提交几次试试,
老赌狗了(不是)
#include <iostream>
using namespace std;
int a[10000020]={0};
int b[10000020]={0};
int main(int argc, char const *argv[])
{
int n,sum=0,k=0;
cin >> n;
int i,j;
for(i=2;i<=n;i++){
if(!a[i]){
b[++k]=i;
}
for(j=1;j<=k && i*b[j]<=n;j++){
a[i*b[j]]=1;
sum++;
if(i%b[j]==0){
break;
}
}
}
cout << k << endl;
return 0;
}
7-2 两个有序链表合并(新表不含重复元素) (20分)
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。 要求S3中没有重复元素。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,要求链表中没有重复元素。数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。
输入样例:
在这里给出一组输入。例如:
1 3 3 5 8 -1
2 3 4 6 8 10 -1
输出样例:
在这里给出相应的输出。例如:
1 2 3 4 5 6 8 10
AC代码
用链表就用链表
(哼
#include<bits/stdc++.h>
using namespace std;
template <typename DataType>
struct Node
{
DataType data; //数据域
Node<DataType> *next; //指针域
};
template <typename DataType>
class LinkList
{
public:
LinkList(); //无参构造函数,建立只有头结点的空链表
LinkList(DataType a[], int n); //有参构造函数,建立有n个元素的单链表
~LinkList(); //析构函数
int Length(); //求单链表的长度
void Insert(DataType x); //插入操作,第i个位置插入值为x的结点
void PrintList( ); //遍历操作,按序号依次输出各元素
private:
Node<DataType> *first; //单链表的头指针
};
template <typename DataType>
LinkList<DataType> :: LinkList( )
{
first = new Node<DataType>; //生成头结点
first->next = nullptr; //头结点的指针域置空
}
template <class DataType>
LinkList<DataType> :: ~LinkList( )
{
Node<DataType> *q = NULL;
while (first != NULL) //释放单链表的每一个结点的存储空间
{
q = first; //暂存被释放结点
first = first->next; // first指向被释放结点的下一个结点
delete q;
}
}
template <typename DataType>
void LinkList<DataType> :: PrintList( )
{
int flag=0;
Node<DataType> *p = first->next; //工作指针p初始化
while (p!= nullptr)
{
if(flag==0){
cout << p->data;
flag=1;
}else{
cout << " "<< p->data ;
}
p = p->next; //工作指针p后移,注意不能写作p++
}
cout<<endl;
}
template <typename DataType>
void LinkList<DataType> :: Insert(DataType x)
{
Node<DataType> *Z = new Node<DataType>;
Z->data = x;
Node<DataType> *p = first, *s = first->next;
if (p->next == nullptr)
{
Z->next = nullptr;
p->next = Z;
p = Z;
return;
}
while (s->data <Z->data&&s->next!=nullptr) //查找第i – 1个结点
{
p = p->next;
s=s->next;
}
if(s->data == Z->data){//元素已存在
delete Z;
return;
}
if(s->data>Z->data){
Z->next = p->next;
p->next = Z;
return;
}
if(s->next==nullptr){
s->next=Z;
Z->next=nullptr;
return;
}
//将结点s插入到结点p之后
}
template <typename DataType>
LinkList<DataType> :: LinkList(DataType a[], int n)
{
first = new Node<DataType>; //生成头结点
Node<DataType> *r = first, *s = nullptr; //尾指针初始化
for (int i = 0; i < n; i++)
{
s = new Node<DataType>;
s->data = a[i];
r->next = s;
r = s; //将结点s插入到终端结点之后
}
r->next = nullptr; //单链表建立完毕,将终端结点的指针域置空
}
int main( )
{
int a;
LinkList<int> L;
int i=0,n;
cin>>a;
while(a!=-1){
L.Insert(a);
//L.PrintList();
cin>>a;
}
int b;
cin>>b;
while(b!=-1){
L.Insert(b);
// L.PrintList();
cin>>b;
}
L.PrintList();
return 0;
}
我就是看set比较顺眼
#include <bits/stdc++.h>
using namespace std;
int main(){
set<int>s;
int a;
cin>>a;
while(a!=-1){
if(s.find(a)==s.end())
s.insert(a);
cin>>a;
}
cin>>a;
while(a!=-1){
if(s.find(a)==s.end())
s.insert(a);
cin>>a;
}
for(set<int>::iterator it=s.begin();it!=s.end();it++){
if(it==s.begin()){
cout<<*it;
}else{
cout<<" "<<*it;
}
}
return 0;
}
7-3 堆栈操作合法性 (20分)
假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。
输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100。
输出格式:
对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。
输入样例:
4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX
输出样例:
YES
NO
NO
NO
AC代码
(跟着他的意思模拟就行)
#include<iostream>
using namespace std;
const int MaxSize=100;
int main()
{
int n,maxx,k,flag=0,i;
cin>>k>>maxx;
string s;
while(k--)
{
cin>>s;
flag=0;
for(i=0; i<s.length(); i++)
{
if(s[i]=='S')
{
flag++;
}
else
{
flag--;
}
if(flag<0||flag>maxx){
cout<<"NO"<<endl;
break;
}
}
if(i==s.length())
{
if(flag==0)
cout<<"YES"<<endl;
else
{
cout<<"NO"<<endl;
}
}
}
return 0;
}
7-4 根据后序和中序遍历输出先序遍历 (25分)
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
Preorder: 4 1 3 2 6 5 7
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template <class DataType>
struct BiNode
{
DataType data;
BiNode<DataType> *lchild, *rchild;
BiNode(DataType n){
data=n;
lchild=NULL;
rchild=NULL;
}
};
template <class DataType>
class BiTree
{
public:
BiTree()
{
int n,i;
cin>>n;
int *h,*z;
h=new int[n];
z=new int[n];
for(i=0; i<n; i++)
{
cin>>h[i];
}
for(i=0; i<n; i++)
{
cin>>z[i];
}
root = Creat(h,z,n);
}
void PreOrder( ){PreOrder(root);}
private:
BiNode<DataType> *Creat(DataType *h,DataType *z,int n); //构造函数调用
BiNode<DataType> *root;
void PreOrder(BiNode<DataType> *bt); //指向根结点的头指针
};
int c=0;
template <class DataType>
void BiTree<DataType> :: PreOrder(BiNode<DataType> *bt)
{
if (bt == nullptr) return; //递归调用的结束条件
else {
if(c==0){
cout <<"Preorder: "<< bt->data;
c=1;
}else{
cout <<" "<< bt->data;
}
//访问根结点bt的数据域
PreOrder(bt->lchild); //前序递归遍历bt的左子树
PreOrder(bt->rchild); //前序递归遍历bt的右子树
}
}
template <class DataType>
BiNode<DataType> *BiTree<DataType> ::Creat(DataType *h,DataType *z,int n){
if(n==0)
return NULL;
int k=0;
while(h[n-1]!=z[k]){
k++;
}
BiNode<DataType> *t=new BiNode<DataType>(h[n-1]);
t->lchild=Creat(h,z,k);
t->rchild=Creat(h+k,z+k+1,n-1-k);
return t;
}
int main( )
{
BiTree<int> asd;
asd.PreOrder();
return 0;
}
简化.省略二叉树
#include <bits/stdc++.h>
using namespace std;
void getpre(int *a,int *b,int n)
{
if(n>0)
{
int root = a[n-1]; //根结点为后序遍历的最后一个
int i;
for(i=0;i<n;i++) //在中序遍历中查找根结点
{
if(b[i] == root)
{
break;
}
}
cout << " " << root;
getpre(a, b, i); //对左子树来查找根结点
getpre(a+i, b+i+1, n-i-1); //对右子树来查找根结点
}
}
int main()
{
int n;
cin >> n;
int a[50],b[50],c[50]; //a[n]后序 b[n]中序
for(int i=0;i<n;i++)
{
cin >> a[i]; //输入后序
}
for(int i=0;i<n;i++)
{
cin >> b[i]; //输入中序
}
cout << "Preorder:";
getpre(a,b,n); //先序
return 0;
}
7-5 哈夫曼编码 (30分)
给定一段文字,如果我们统计出字母出现的频率,是可以根据哈夫曼算法给出一套编码,使得用此编码压缩原文可以得到最短的编码总长。然而哈夫曼编码并不是唯一的。例如对字符串"aaaxuaxz",容易得到字母 ‘a’、‘x’、‘u’、‘z’ 的出现频率对应为 4、2、1、1。我们可以设计编码 {‘a’=0, ‘x’=10, ‘u’=110, ‘z’=111},也可以用另一套 {‘a’=1, ‘x’=01, ‘u’=001, ‘z’=000},还可以用 {‘a’=0, ‘x’=11, ‘u’=100, ‘z’=101},三套编码都可以把原文压缩到 14 个字节。但是 {‘a’=0, ‘x’=01, ‘u’=011, ‘z’=001} 就不是哈夫曼编码,因为用这套编码压缩得到 00001011001001 后,解码的结果不唯一,“aaaxuaxz” 和 “aazuaxax” 都可以对应解码的结果。本题就请你判断任一套编码是否哈夫曼编码。
输入格式:
首先第一行给出一个正整数 N(2≤N≤63),随后第二行给出 N 个不重复的字符及其出现频率,格式如下:
c[1] f[1] c[2] f[2] … c[N] f[N]
其中c[i]是集合{‘0’ - ‘9’, ‘a’ - ‘z’, ‘A’ - ‘Z’, ‘_’}中的字符;f[i]是c[i]的出现频率,为不超过 1000 的整数。再下一行给出一个正整数 M(≤1000),随后是 M 套待检的编码。每套编码占 N 行,格式为:
c[i] code[i]
其中c[i]是第i个字符;code[i]是不超过63个’0’和’1’的非空字符串。
输出格式:
对每套待检编码,如果是正确的哈夫曼编码,就在一行中输出"Yes",否则输出"No"。
注意:最优编码并不一定通过哈夫曼算法得到。任何能压缩到最优长度的前缀编码都应被判为正确。
输入样例:
7
A 1 B 1 C 1 D 3 E 3 F 6 G 6
4
A 00000
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11
输出样例:
Yes
Yes
No
No
AC代码
#include <iostream>
using namespace std;
struct ElemType
{
int weight; //假定权值为整数
int parent, lchild, rchild; //游标
};
class HuffmanTree
{
public:
HuffmanTree(int w[ ], int n);
HuffmanTree( );
int Print( );
private:
ElemType *huffTree;
int num;
void Select(int n, int &i1, int &i2);
};
void HuffmanTree :: Select(int n, int &i1, int &i2)
{
int i = 0, temp;
for ( ; i < n; i++)
if (huffTree[i].parent == -1) {i1 = i; break;}
for (i = i + 1; i < n; i++)
if (huffTree[i].parent == -1) {i2 = i;break;}
if (huffTree[i1].weight > huffTree[i2].weight)
{
temp = i1; i1 = i2;i2 = temp;
}
for (i = i + 1; i < n; i++)
{
if (huffTree[i].parent == -1)
{
if (huffTree[i].weight < huffTree[i1].weight)
{
i2 = i1; i1 = i;
}
else if (huffTree[i].weight < huffTree[i2].weight)
{
i2 = i;
}
}
}
}
HuffmanTree :: HuffmanTree(int w[ ], int n)
{
int i, k, i1, i2;
huffTree = new ElemType [2*n-1];
num = n;
for (i = 0; i < 2*num-1; i++) //初始化,所有结点均没有双亲和孩子
{
huffTree[i].parent = -1;
huffTree[i].lchild = huffTree[i].rchild = -1;
}
for (i = 0; i < num; i++) //存储叶子结点的权值
huffTree[i].weight = w[i];
for (k = num; k < 2*num-1; k++) //n-1次合并
{
Select(k, i1, i2); //权值最小的根结点下标为i1和i2
huffTree[k].weight = huffTree[i1].weight + huffTree[i2].weight;
huffTree[i1].parent = k; huffTree[i2].parent = k;
huffTree[k].lchild = i1; huffTree[k].rchild = i2;
}
}
int HuffmanTree :: Print( )
{
int i, k;
int sum=0;
//cout << "每个叶子到根结点的路径是:" << endl;
for (i = 0; i < num; i++)
{
//cout << huffTree[i].weight;
int cnt=0;
k = huffTree[i].parent;
while (k != -1)
{
cnt++;
//cout << "-->" << huffTree[k].weight;
k = huffTree[k].parent;
}
sum+=cnt*huffTree[i].weight;
//cout <<cnt*huffTree[i].weight<< endl;
}
return sum;
}
int main( )
{
int n,w[100],i,t;
cin>>n;
string s[100];
char a;
for(i=0; i<n; i++)
{
cin>>a>>w[i];
}
HuffmanTree T{w, n};
int sum=T.Print();
cin>>t;
while(t--)
{
int sum2=0;
for(i=0; i<n; i++)
{
cin>>a>>s[i];
sum2+=s[i].length()*w[i];
}
if(sum2!=sum)
{
cout<<"No"<<endl;
}
else
{
int flag=0,j;
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
if(s[i].length()==s[j].length())
{
if(s[i]==s[j])
{
flag=1;
}
}
else
{
int flag1=1;
for(int k=0; k<min(s[i].length(),s[j].length()); k++)
{
if(s[i][k]!=s[j][k])
{
flag1=0;
break;
}
}
if(flag1==1)
{
flag=1;
break;
}
}
}
if(flag==1){
break;
}
}
if(flag==0){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
}
return 0;
}
简化.省略哈夫曼树
#include<bits/stdc++.h>
using namespace std;
int main(){
int s = 0, n, m, x, a[100];
char ch;
priority_queue<int,vector<int>,greater<int> > q; //优先队列
cin>>n;getchar();
for(int i = 0; i < n; i++) {
cin>>ch>>x;
a[i] = x;
q.push(x);
}
while(q.size() > 1) {
int x = q.top();
q.pop();
int y = q.top();
q.pop();
s = s + x + y;
q.push(x + y);
}
cin>>m;
while(m--) {
int s1 = 0;
string str[100];
for(int i = 0; i < n; i++) {
cin>>ch>>str[i];
s1 = s1 + str[i].size() * a[i];
}
if(s == s1) {
bool jdg = true;
for (int i = 0; i < n-1; i++) {//字符串两两比较前缀是不是相同
for (int j = i+1; j < n; j++) {
int flag = 0;
int size=min(str[j].size() , str[i].size());
for(int k = 0; k < size; k++)
if(str[i][k] != str[j][k])
flag = 1;//有一位不一样就可以
if (!flag)
jdg = false;
}
}
if(jdg)
cout<<"Yes\n";
else
cout<<"No\n";
}
else
cout<<"No\n";
}
return 0;
}
7-6 学生顺序表的建立 (10分)
完成对一个顺序表的建立,表中的每个元素是同学们的学号、姓名和三门课程的成绩,输入5个同学的信息,然后显示在屏幕上。(要求利用顺序表的基本操作)
输入格式:
首先收入学生人数5,然后依次输入5个学生的学号、姓名和三门课的成绩
输出格式:
输入5个学生的学号、姓名和三门课的成绩
输入样例:
5 01 张三 89 89 89 02 李四 90 90 90 03 王五 89 89 89 04 钱六 97 97 97 05 赵倩 90 90 90
输出样例:
1 张三 89.0 89.0 89.0 2 李四 90.0 90.0 90.0 3 王五 89.0 89.0 89.0 4 钱六 97.0 97.0 97.0 5 赵倩 90.0 90.0 90.0
AC代码
#include <bits/stdc++.h>
using namespace std;
#define MAXSIZE 1000
struct sz{
int no;
string name;
double x,y,z;
};
class Seqlist
{
public:
int length;
sz date[MAXSIZE];
Seqlist(sz a[],int n)
{
for(int i=0; i<n; i++)
{
date[i]=a[i];
}
length=n;
}
void print()
{
for(int i=0; i<length; i++)
{
cout<<setiosflags(ios::fixed)<<setprecision(1);
cout<<date[i].no<<" "<<date[i].name<<" "<<date[i].x<<" "<<date[i].y<<" "<<date[i].z<<endl;
}
}
};
int main()
{
int n,i;
cin>>n;
sz a[MAXSIZE];
for(i=0;i<n;i++){
cin>>a[i].no;
cin>>a[i].name;
cin>>a[i].x;
cin>>a[i].y;
cin>>a[i].z;
}
Seqlist l(a,n);
l.print();
}
要是我知道测试点是什么连这几行都不想写
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,i;
cin>>n;
int no;
string name;
double x,y,z;
for(i=0;i<n;i++){
cin>>no>>name>>x>>y>>z;
cout<<setiosflags(ios::fixed)<<setprecision(1);
//背不过这一句就换printf保留一位小数
cout<<no<<" "<<name<<" "<<x<<" "<<y<<" "<<z<<endl;
}
return 0;
}
7-7 求两个一元多项式的和 (20分)
求两个一元多项式的和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分1行,分别以指数递降方式输出和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例1:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例1:
5 20 -4 4 -5 2 9 1 -2 0
AC代码
#include <iostream>
using namespace std;
struct Node //定义多项式链表的结点
{
int coef, exp; // coef表示系数,exp表示指数
Node *next;
};
class Polynomial
{
public:
Polynomial( ); //构造函数
~Polynomial( ); //析构函数,同单链表析构函数
Polynomial(const Polynomial &B); //拷贝构造函数
Polynomial operator + (Polynomial &B); //重载运算法,多项式相加
void Print( ); //打印一元多项式
private:
Node *first;
};
Polynomial::~Polynomial( )
{
Node *q = nullptr;
while (first != nullptr) //释放单链表的每一个结点的存储空间
{
q = first; //暂存被释放结点
first = first->next; // first指向被释放结点的下一个结点
delete q;
}
}
Polynomial :: Polynomial(const Polynomial &B){
first = B.first;
}
Polynomial :: Polynomial( )
{
Node *r = nullptr, *s = nullptr;
int coef, exp;
first = new Node; //申请头结点
r = first; r->next = nullptr; //尾插法建立单链表
//cout<<"sr xs zs:";
int nnn;
cin>>nnn;
while(nnn--){
cin >> coef >> exp;
s = new Node; s->coef = coef; s->exp = exp;
r->next = s; r = s;
}
//cout << "请输入系数和指数:";
//输入第一项的系数和指数
//while (coef != 0 && exp != 0) //循环结束的条件是输入系数为0
//{
//将结点s插入单链表的尾部
//cout<<"sr xs zs:";
//cout << "请输入系数和指数:";
//cin >> coef >> exp;
//}
r->next = nullptr;
}
Polynomial Polynomial :: operator + (Polynomial &B)
{
Node *pre = first, *p = pre->next; //工作指针pre和p初始化
Node *qre = B.first, *q = qre->next; //工作指针qre和q初始化
Node *qtemp = nullptr;
while (p != nullptr && q != nullptr)
{
if (p->exp > q->exp) { //第1种情况
pre = p; p = p->next;
}
else if (p->exp < q->exp) { //第2种情况
qtemp = q->next;
pre->next = q; //将结点q插入到结点p之前
q->next = p;
q = qtemp;
pre = q;
qre->next = q;
}
else { //第3种情况
p->coef = p->coef + q->coef;
if (p->coef == 0) { //系数相加为0,则删除结点p
pre->next = p->next;
delete p;
p = pre->next;
}
else { //系数不为0
pre = p; p = p->next;
}
qre->next = q->next; //第3种情况都要删除结点q
delete q;
q = qre->next;
}
}
if (p == nullptr) pre->next = q; //将结点q链接在第一个单链表的后面
B.first->next = nullptr;
return *this;
}
void Polynomial :: Print( )
{
Node *p = first->next;
if(p==nullptr){
cout<<0<<" "<<0<<endl;
return;
}
if (p != nullptr)
cout << p->coef << " " << p->exp;
p = p->next;
while (p != nullptr)
{
if (p->coef > 0)
cout << " " << p->coef << " " << p->exp;
else
cout << " "<< p->coef << " " << p->exp;
p = p->next;
}
cout << endl;
}
int main( )
{
Polynomial A{ };
//A.Print( );
Polynomial B{ }; //定义多项式A和B
//B.Print( );
Polynomial C = A + B;
//printf("结果是:");
C.Print( ); //输出相加结果
return 0;
}
看map顺眼的很
#include <bits/stdc++.h>
using namespace std;
int main()
{
map<int,int>mp;
int n,x,y,i,cnt=0;
cin>>n;
for(i=0;i<n;i++){
cin>>x>>y;
mp[y]+=x;
}
cin>>n;
for(i=0;i<n;i++){
cin>>x>>y;
mp[y]+=x;
}
for(map<int,int>::iterator it=mp.end(); it!=mp.begin();)
{
it--;
if(it->second!=0)
{
if(cnt==0)
{
cout<<it->second<<" "<<it->first;
cnt++;
}
else
{
cout<<" "<<it->second<<" "<<it->first;
cnt++;
}
}
}
if(cnt==0){
cout<<0<<" "<<0<<endl;
}
return 0;
}