【机试】比较好的题目~

1、

统计节点个数
时间限制 1000 ms 内存限制 65536 KB

题目描述
给出一棵有向树,一共有N(1<N≤1000)个节点,如果一个节点的度(入度+出度)不小于它所有儿子以及它父亲的度(如果存在父亲或儿子),那么我们称这个节点为p节点,现在你的任务是统计p节点的个数。

如样例,第一组的p节点为1,2,3;第二组的p节点为0。

输入格式
第一行为数据组数T(1≤T≤100)。
每组数据第一行为N表示树的节点数。后面为N−1行,每行两个数x,y(0≤x,y<N),代表y是x的儿子节点。

输出格式
每组数据输出一行,为一个整数,代表这棵树上p节点的个数。

输入样例
2
5
0 1
1 2
2 3
3 4
3
0 2
0 1
输出样例
3
1

邻接矩阵做法

 1 #include<bits/stdc++.h>
 2 using namespace std;
  const int maxn=1000;
3 int du[maxn]={0}; 4 int edge[maxn][maxn]={0}; 5 int main(){ 6 int T; 7 scanf("%d",&T); 8 while(T--){ 9 memset(du,0,sizeof(du)); 10 memset(edge,0,sizeof(edge)); 11 int n; 12 scanf("%d",&n);13 int fa,son,max_node,cnt=0; 14 for(int i=0;i<n-1;i++){ 15 scanf("%d %d",&fa,&son);16 du[fa]++; 17 du[son]++; 18 edge[fa][son]=edge[son][fa]=1; 19 } 20 for(int i=0;i<n;i++){//遍历图 21 max_node=0; 22 for(int j=0;j<n;j++){ 23 if(i!=j&&edge[i][j]){ 24 max_node=max(max_node,du[j]); 25 } 26 } 27 if(du[i]>=max_node) cnt++; 28 } 29 cout<<cnt<<endl; 30 } 31 return 0; 32 }

 

邻接表做法(...)

2、

 

题目描述

 

    读入一组字符串(待操作的),再读入一个int n记录记下来有几条命令,总共有2中命令:1、翻转  从下标为i的字符开始到i+len-1之间的字符串倒序;2、替换  命中如果第一位为1,用命令的第四位开始到最后的字符串替换原读入的字符串下标 i 到 i+len-1的字符串。每次执行一条命令后新的字符串代替旧的字符串(即下一条命令在作用在得到的新字符串上)。     命令格式:第一位0代表翻转,1代表替换;第二位代表待操作的字符串的起始下标int i;第三位表示需要操作的字符串长度int len。

输入描述:

输入有多组数据。
每组输入一个字符串(不大于100)然后输入n,再输入n条指令(指令一定有效)。

输出描述:

根据指令对字符串操作后输出结果。
示例1

输入

bac
2
003
112as

输出

cab
cas
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     string s,order[100];
 5     int n;
 6     while(cin>>s>>n){
 7         for(int i=0;i<n;i++)
 8             cin>>order[i];
 9         for(int i=0;i<n;i++){
10             int option=order[i][0]-'0',start=order[i][1]-'0',len=order[i][2]-'0';//注意字符和整数的转化
11             if(option==0) reverse(s.begin()+start,s.begin()+start+len);//翻转函数使用格式
12             else s.replace(start,len,order[i].substr(3));
13             cout<<s<<endl;
14         }
15     }
16     return 0;
17 }

 

 题目来源:2014北邮计算机学院机试

这个题不是很难,但是初读觉得比较新颖吧,结合了OS的知识~

 

Problem  B. 内存分配
题目描述
在操作系统中,内存分配是非常重要的工作。
已知内存空间由N个内存块组成,这些内存块从1到N编号,进行内存分配时,操作系统将选择一块大小足够的内存全部分配给请求内存的进程。例如,当进程请求10MB的内存时,操作系统必须向该进程分配一个不小于10MB的内存块。内存块不能被重复分配。
操作系统有三种基本的分配方式,分别为:
首次适应:从1号到N号内存块依次查找,直到找到第一块足够大的且未分配出去的内存块,将其分配给进程。
最佳适应:找到当前未分配出去且大小足够的内存块中最小的内存块分配给进程。

最差适应:找到当前未分配出去且大小足够的内存块中最大的内存块分配给进程。
其中,最佳适应是应用最为广泛的分配方式。现在,操作系统要依次处理M个进程的内存请求,请按照最佳适应方式分配内存,并输出相应分配到的内存块的大小。如果没有大小足够的内存块可以满足当前请求,则输出“NULL”(不包含引号),并跳出该请求。

输入格式

输入数据的第一行是测试数据组数T(T<=50)
每组数据由4行构成:
第一行为一个整数N(1<=N<=100),表示有N个内存块。
第二行有N个整数,第i个整数表示第i块内存块的大小。
第三行为一个整数M(1<=M<=100),表示有M个请求。
第四行有M个整数,表示进程所请求的内存空间。
输出格式
每组数据输出一行,每行有M个数,表示操作系统采用最佳适应方式,依次分配给进程的内存块大小;如果没有可用的内存块,输出“NULL”(不包含引号)
请不要输出多余的行尾空格,否则会被判为格式错误。

 

输入样例

2

4
7 5 10 3

2

4 6

4
3 5 9 10 

3

5 12 6
输出样例
5 7

 

5 NULL 9

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     cin>>T;
 6     while(T--){
 7         int n;
 8         cin>>n;
 9         int a[n],flag=0;
10         bool visit[50];
11         for(int i=0;i<n;i++){
12             cin>>a[i];
13             visit[i]=false;
14         }
15         int m;
16         cin>>m;
17         int b[m];
18         for(int i=0;i<m;i++){
19             cin>>b[i];
20         }
21         sort(a,a+n);
22         for(int i=0;i<m;i++){
23             flag=0;
24             for(int j=0;j<n;j++){
25                 if(a[j]>=b[i]&&visit[j]==false){
26                     flag=1;
27                     cout<<a[j]<<' ';
28                     visit[j]=true;
29                     break;
30                 }
31             }
32             if(flag==0) cout<<"NULL"<<' ';
33         }
34          cout<<endl;
35     }
36     return 0;
37 }

 题目来源:2014网研机试题目

题目描述
给定一棵带权二叉树,请判断它是不是一个最小堆。
一棵二叉树是一个最小堆,当且仅当对于树上任意一个节点,它的权值都小于或等于以它为根的子树中的所有权值。

输入格式
输入数据第一行是一个整数T(1<=T<=100),表示测试数据的组数。
对于每组测试数据:
第一行是一个整数N(1<=N<=100),表示树的节点个数。
接下来一行包含N个正整数,第i个整数valuei(1<=valuei<=1000)表示编号i的点的权值。
接下来N-1行,每行两个整数u和v(1<=u,v<=N, u!=v),表示节点u是节点v的父节点。
测试数据保证给定的一定是一棵二叉树,并且节点1是树的根结点。

输出格式
对于每组测试数据,如果给定的树是一个最小堆则输出Yes,否则输出No。

输入样例

3
1
10
3
10 5 3
1 2
1 3
5
1 2 3 4 5
1 3
1 2
2 4
2 5

输出样例
Yes
No
Yes

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     cin>>T;
 6     while(T--){
 7         int n,flag=0;
 8         cin>>n;
 9         int a[n];
10         for(int i=0;i<n;i++){
11             cin>>a[i];
12         }
13         n--;
14         for(int i=0;i<n;i++){
15             int u,v;
16             cin>>u>>v;
17             if(a[u]>a[v]){
18                 flag=1;
19             }
20         }
21         if(flag) cout<<"No"<<endl;
22         else cout<<"Yes"<<endl;
23     }
24     return 0;
25 }

 题目链接:https://blog.csdn.net/weixin_44312186/article/details/88836969

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int n,m;
 5     while(cin>>n>>m){
 6         string s;
 7         char a[n];
 8         for(int i=0;i<n;i++){
 9             cin>>a[i];
10             s+=a[i];//使用string方便调用库函数
11         }
12         for(int i=0;i<m;i++){
13             int type,l,r;
14             cin>>type>>l>>r;
15             switch (type){
16                 case 1:{
17                     reverse(s.begin()+l-1,s.begin()+r);
18                     //cout<<s<<endl;
19                     break;
20                 }case 2:{
21                     int len;
22                     cin>>len;
23                     int tmp;
24                     for(int i=0;i<len;i++){
25                         tmp=s[l-1];
26                         s[l-1]=s[r-1];
27                         s[r-1]=tmp;
28                         l++;
29                         r++;
30                     }
31                     //cout<<s<<endl;
32                     break;
33                 }case 3:{
34                     char x;
35                     cin>>x;
36                     for(int i=l-1;i<=r-1;i++){
37                         s[i]=x;
38                     }
39                     //cout<<s<<endl;
40                     break;
41                 }case 4:{
42                     sort(s.begin()+l-1,s.begin()+r);
43                     //cout<<s<<endl;
44                     break;
45                 }case 5:{
46                     int sum=0;
47                     for(int i=l-1;i<=r-1;i++){
48                         sum+=s[i]-'0';
49                     }
50                     cout<<sum<<endl;
51                     break;
52                 }
53             }
54         }
55     }
56     return 0;
57 }

 

Problem_C(链表操作):
一个出值为 1,2,3,4,…,n的n(0<n<=50)个节点的顺序链表,有以下3种操作方式:
1 移除节点值为x的节点
2 翻转链表,对调整个链表的顺序
3 查询链表值为x的节点所指的下一个节点的值

输入:
第一行输入T,表示数据的组数
每组第一行输入 n (表示节点数目) m (表示操作数目)
接下来m行分别输入 ope (操作方式) x (操作的节点值,操作方式为2时不会输入该值)

1
6 6
3 6
1 2
3 1
2
1 5
3 6
1
2
3
4
5
6
7
8
输出:
输出操作为3查询时,所查节点所指的下一个节点值,若没有查到或查到的节点为表尾 (没有下一节点),输出"NONE"

NONE
3
4

用字符串同样可以达到顺序链表的效果。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     cin>>T;
 6     while(T--){
 7         int n,m;
 8         cin>>n>>m;
 9         string s;
10         for(int i=1;i<=n;i++){
11             s+=i+'0';
12         }//建立顺序链表
13         for(int i=0;i<m;i++){
14             int op;
15             cin>>op;
16             switch(op){
17                 case 1:{//删除操作
18                     int x;
19                     cin>>x;
20                     for(int i=0;i<s.size()-1;i++){
21                         if(s[i]==x+'0'){
22                             for(int j=i;j<s.size();j++)
23                                 s[j]=s[j+1];
24                         }
25                     }
26                     if(s[s.size()-1]==x+'0') s.erase(s.end()-1);
27                     //cout<<s<<endl;
28                     break;
29                 }case 2:{//翻转操作
30                     reverse(s.begin(),s.end());
31                     //cout<<s<<endl;
32                     break;
33                 }case 3:{//查询操作
34                     int x,flag=0;
35                     cin>>x;
36                     for(int i=0;i<s.size()-1;i++){
37                         if(s[i]==x+'0'){
38                             flag=1;
39                             cout<<s[i+1]<<endl;
40                         }
41                     }
42                     if(flag==0) cout<<"NONE"<<endl;
43                     break;
44                 }
45 
46             }
47         }
48     }
49     return 0;
50 }

 10进制转2进制

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int n;
 5     while(cin>>n){
 6         stack<int>my;//用vector也可以
 7         while(n!=0){
 8             my.push(n%2);
 9             n/=2;
10         }
11         while(!my.empty()){
12             cout<<my.top();
13             my.pop();
14         }
15         cout<<endl;
16     }
17     return 0;
18 }

 

求质因数的个数

求正整数N(N>1)的质因数的个数。 相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int slv(int n){
 4     int cnt=0;
 5     for(int i=2;i<=sqrt(n);i++){//sqrt减少时间复杂度
 6         while(n%i==0){
 7             n/=i;
 8             cnt++;
 9         }
10     }
11     if(n>1) cnt++;
12     return cnt;
13 }
14 int main(){
15     int n;
16     while(cin>>n){
17         cout<<slv(n)<<endl;
18     }
19     return 0;
20 }

DFS

有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int ans=0,n,a[20];
 4 void dfs(int sum,int now){
 5     if(sum==40){
 6         ans++;
 7         return;
 8     }else{
 9         for(int i=0;i<n;i++){
10             if(i>now){
11                 sum+=a[i];
12                 dfs(sum,i);
13                 sum-=a[i];
14             }
15         }
16     }
17 }
18 int main(){
19     while(cin>>n){
20         ans=0;
21         for(int i=0;i<n;i++){
22             cin>>a[i];
23         }
24         dfs(0,-1);
25         cout<<ans<<endl;
26     }
27     return 0;
28 }

 

posted @ 2020-04-16 18:25  岩烧店的烟味弥漫  阅读(206)  评论(0)    收藏  举报