黑马程序员--C语言算法十例(上)

本文探讨了ASP.Net、Unity开发以及.NET培训的相关话题,并提供了几个具体问题的解决方案,包括活动安排、哈夫曼编码、括号配对等编程问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

----------------------ASP.Net+Unity开发.Net培训期待与您交流! ----------------------



一、会场安排问题

描述

学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。

输入

第一行是一个整型数m(m<100)表示共有m组测试数据。
每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。
随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)

输出

对于每一组输入,输出最多能够安排的活动数量。
每组的输出占一行

样例输入

2

2

1 10

10 11

3

1 10

10 11

11 20

样例输出

1

2

提示

注意:如果上一个活动在t时间结束,下一个活动最早应该在t+1时间开始

 

程序示例:

#include<stdio.h>
#include <vector>
#include<algorithm>
#include<math.h>
using namespace std;
 
struct activ
{
       intbegin;
       intend;
};
bool cmp( activ a,activ b)
{
       returna.end<b.end;
}
int main()
{
       //freopen("1.txt","r",stdin);
       intn;
       scanf("%d",&n);
       while(n--)
       {
              intm;
              scanf("%d",&m);
              vector<activ>vec;
              for(inti=0;i<m;i++)
              {
                     activa;
                     scanf("%d%d",&a.begin,&a.end);
                     vec.push_back(a);
              }
             
              sort(vec.begin(),vec.end(),cmp);  
              intcount=vec.size();
              intk=0;
              for(int i=1;i<vec.size();i++)
              {
                     if(vec[i].begin<= vec[k].end)
                            count--;
                     elsek=i;
              }
              printf("%d\n",count);
       }
      
       return0;
}       

二、Haffman编码

 

描述

哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去。。。)。现在给你一串字符以及它们所对应的权值,让你构造哈弗曼树,从而确定每个字符的哈弗曼编码。当然,这里有一些小规定:

1.规定哈弗曼树的左子树编码为0,右子树编码为1

2.若两个字符权值相同,则ASCII码值小的字符为左孩子,大的为右孩子;

3.创建的新节点所代表的字符与它的左孩子的字符相同;

4.所有字符为ASCII码表上32-96之间的字符(即“ ”“`”之间的字符)。

输入

输入包含多组数据(不超过100组)
每组数据第一行一个整数n,表示字符个数。接下来n行,每行有一个字符ch和一个整数weight,表示字符ch所对应的权值,中间用空格隔开。
输入数据保证每组测试数据的字符不会重复。

输出

对于每组测试数据,按照输入顺序输出相应的字符以及它们的哈弗曼编码结果,具体格式见样例。

样例输入

3

a 10

b 5

c 8

4

a 1

b 1

c 1

d 1

样例输出

a:0

b:10

c:11

a:00

b:01

c:10

d:11

 

 程序示例:

#include"stdio.h"
#include"stdlib.h"
typedef struct{
       intweight;
       intparent,lchild,rchild;
}huffman;
char a[200];
int w[101];
int select(huffman *huff,int n){
       inti,temp=100000000,s;
       for(i=0;i<=n;i++){
              if(huff[i].parent== 0){
                     if(huff[i].weight< temp){
                            s=i;
                            temp= huff[i].weight;
                     }elseif(huff[i].weight == temp&&a[i]<a[s]){
                            s=i;
                            temp= huff[i].weight;
                     }
              }
       }
       returns;
}
int main(){
       intn,i,s1,s2,m,start,c,f;
       huffman*huff;
       char*ch;
       while(scanf("%d",&n)!=EOF){
              for(i=0;i<n;i++){
                     getchar();
                     scanf("%c%d",&a[i],&w[i]);
              }
                     m= 2*n -1;
                     huffman*p;
                     huff= (huffman *)malloc(sizeof(huffman)*(m+1));
                     for(p=huff,i=0;i<n;i++,p++){
                            p->weight= w[i];
                            p->lchild= 0;
                            p->parent=0;
                            p->rchild= 0;
                     }
                     for(i=n;i<m;i++,p++){
                            p->weight= 0;
                            p->lchild= 0;
                            p->parent=0;
                            p->rchild= 0;
                     }
                     for(i= n;i < m;i++){
                            s1=select(huff,i-1);
                            huff[s1].parent= i;
                            s2=select(huff,i-1);
                            huff[s2].parent=i;
                            huff[i].weight = huff[s1].weight +huff[s2].weight;
                            a[i]= a[s1];
                            huff[i].lchild= s1; huff[i].rchild = s2;
                     }
                     ch= (char *)malloc(sizeof(char)*n);
                     ch[n-1]= '\0';
                     for(i=0;i<n;i++){
                            start= n-1;
                            for(c=i,f=huff[i].parent;f!=0;c=f,f=huff[f].parent)
                                   if(huff[f].lchild== c) ch[--start] = '0';
                                   elsech[--start] = '1';
                            printf("%c:%s\n",a[i],ch+start);
                     }
       }
       return0;
}


       

三、括号配对问题

描述

现在,有一行括号序列,请你检查这行括号是否配对。

输入

第一行输入一个数N0<N<=100,表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符

输出

每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No

样例输入

3

[(])

(])

([[]()])

样例输出

No

No

Yes

 

  程序示例:

#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
       intn;
       cin>>n;
       while(n--)
       {    
              vector<char>vec;
              stringch;
              vec.push_back('');
              cin>>ch;
              for(inti=0;i<ch.length();i++)
              {
                     vec.push_back(ch[i]);
                  if( vec.back()-1 == *(vec.end()-2) ||vec.back()-2 == *(vec.end()-2))
                     {
                            vec.pop_back();
                            vec.pop_back();
                     }
              }
              if(vec.size()==1)
                     cout<<"Yes"<<endl;
              else
                     cout<<"No"<<endl;
       }
       return0;
}       
 

四、括号匹配(二)

 

描述

给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]
是匹配的
([])[]
是匹配的
((]
是不匹配的
([)]
是不匹配的

输入

第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串SS中只包含以上所说的四种字符,S的长度不超过100

输出

对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行

样例输入

4

[]

([])[]

((]

([)]

样例输出

0

0

3

2

 

 程序示例:

#include<iostream>
#include<cstdio>
#include<cstring>
 
using namespace std;
const int maxn=110;
char tab[maxn];
int f[maxn][maxn];
 
int fun(int i,int j)
{
       if(i>j)return0;
       if(f[i][j]>=0)returnf[i][j];
       if(i==j)returnf[i][j]=1;
       intva=maxn;
       if((tab[i]=='('&&tab[j]==')')|| (tab[i]=='['&&tab[j]==']'))
              va=fun(i+1,j-1);
       for(intmid=i;mid<j;mid++){
              va=min(va,fun(i,mid)+fun(mid+1,j));
       }
       returnf[i][j]=va;
}
 
int main()
{
        
       intn;
       scanf("%d",&n);
       for(inti=0;i<n;i++){
              memset(f,-1,sizeof(f));
              memset(tab,0,sizeof(tab));
              scanf("%s",tab);
              cout<<fun(0,strlen(tab)-1)<<endl;
       }
}       


 

五、单调递增最长子序列

 

描述

求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4

输入

第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000

输出

输出字符串的最长递增子序列的长度

样例输入

3

aaa

ababc

abklmncdefg

样例输出

1

3

7

 

 程序示例:

#include<iostream>
#include <string>
//#include <time.h>
using namespace std;
int main()
{
       //freopen("1.txt","r",stdin);
       intn ;
       cin>>n;
       while(n--)
       {
              stringstr;
              intcount=1;
              cin>>str;
              inta[200];
              a[0]=-999;
              for(int i=0;i<str.length();i++)
              {
 
                     for(int j=count-1;j>=0;j--)
                     {
                            if((int)str[i]>a[j])
                            {
                                   a[j+1]=str[i];
                                   if(j+1==count)count++;
                                   break;
                            }
                     }
              }
              cout<<count-1<<endl;
       }
       //cout<<(double)clock()/CLOCKS_PER_SEC<<endl;
       return0;
}       


 

----------------------ASP.Net+Unity开发.Net培训期待与您交流! ----------------------


详细请查看:www.itheima.com

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值