机试复试准备中--梦校(华科)真题

  • 一、矩阵转置
  • 二、统计单词
    • 写法一:读取一整行
    • 写法二:依次读入每一个单词
  • 三、二叉排序树(DFS)
  • 四、IP地址
  • 五、特殊排序
  • 六、a+b(高精度加法)
  • 七、奇偶校验
  • 八、最大的两个数
  • 九、二叉树遍历(DFS)
  • 十、成绩排序
  • 十一、守形数
  • 十二、矩阵最大值
  • 十三、最小年龄的3个职工(结构体排序)
  • 十四、对称矩阵
  • 十五、A+B(读取问题)
  • 十六、打印日期(闰年的判断)
    • 写法一:for
  • 写法二:while更好
  • 十七、大数排序
  • 二十、回文字符串
  • 二十一、找位置(STL容器)
  • 二十二、阶乘
  • 二十三、八进制
  • 二十四、最长&最短文本(STL)
  • 二十五、梅森素数(素数)
  • 二十六、单词个数统计
  • 二十七、进制转换(巧)
  • 二十八、排序去重
  • 二十九、十进制加密
  • 三十、删除数字(贪心)

看了最近几年的夏令营的真题,感觉不算特别难,相对于有算法经历的人来说不算难,但是可能对我这种掌握的不是很好的人来说,很难拿到满分。

机试:2h,4道题
会有成绩排名

一、矩阵转置

机试复试准备中--梦校(华科)真题_第1张图片
这题应该是放在第一道题。很简单,考察的二维数组的应用。

#include

using namespace std;
const int N=100;
int a[N][N];

int main()
{
    int n;
    cin>>n;
    for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
        cin>>a[i][j];
   for (int i=0;i<n;i++)
    for (int j=0;j<n;j++)
       {
         cout<<a[j][i];
         if (j==n-1)
            cout<<endl;
         else cout<<" ";
       }

    return 0;
}

二、统计单词

机试复试准备中--梦校(华科)真题_第2张图片
这也是很简单的一道题,主要就是如何读取这一行。

写法一:读取一整行

getline(cin,s)可以读取一行。

#include

using namespace std;

int main()
{
    string s;
    getline(cin,s);
    int ans=0,f=0;
    for(int i=0;i<s.length();i++)
    {
        if (s[i]=='.')cout<<ans;
       if (s[i]!=' ')ans+=1,f=0;
       if (s[i]==' '&&f==0)
       {
           cout<<ans<<" ";
           ans=0;
           f=1;
       }

    }
    return 0;
}

写法二:依次读入每一个单词

#include
using namespace std;

int main()
{
    string st;
    while(cin>>st){
        if(st[st.size()-1]!='.')cout<<st.size()<<' ';
        else cout<<st.size()-1<<' ';
    }
}

三、二叉排序树(DFS)

机试复试准备中--梦校(华科)真题_第3张图片
递归建树
开始时根节点为 −1
遍历发现比根节点大则遍历右子树
反之遍历左子树

#include

using namespace std;
const int N=110;
int n;
int root;
unordered_map<int,int>l,r;

int dfs(int f,int x)
{
    if(f==-1)
    {
        root=x;
        return f;
    }
    if (x>f)
    {
        if(!r.count(f))/检查这个元素是否存在
        {
            r[f]=x;
            return f;
        }
        else return dfs(r[f],x);
    }
    if(x<f)
    {
        if(!l.count(f))
        {
            l[f]=x;
            return f;
        }
        else return dfs(l[f],x);
    }
    
}

int main()
{
    cin>>n;
    root=-1;
    int x;
    while(n--)
    {
        cin>>x;
        cout<<dfs(root,x)<<endl;
    }
    return 0;
}


四、IP地址

机试复试准备中--梦校(华科)真题_第4张图片

#include

using namespace std;

bool check(int a)
{
    if(0<=a&&a<=255)
        return true;
    return false;
}

int main()
{
    int a,b,c,d;
    while(~scanf("%d.%d.%d.%d",&a,&b,&c,&d))
    {
        if(check(a)&&check(b)&&check(c)&&check(d))
            printf("Yes!\n");
        else printf("No!\n");
    }
    return 0;
}

五、特殊排序

机试复试准备中--梦校(华科)真题_第5张图片

#include

using namespace std;

const int N=1010;
int a[N];

int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    cout<<a[n-1]<<endl;
    if(n==1) cout<<"-1";
    else for (int i=0;i<n-1;i++)
    cout<<a[i]<<" ";
    return 0;
}

六、a+b(高精度加法)

机试复试准备中--梦校(华科)真题_第6张图片

#include

using namespace std;

int a[1010],b[1010],c[1010];

int main()
{
    string s1,s2;
    while(cin>>s1>>s2)
    {
        memset(a,0,sizeof a);
        memset(b,0,sizeof b);
        memset(c,0,sizeof c);
        for(int i=0;i<s1.length();i++)a[i]=s1[s1.length()-i-1]-'0';
        for(int i=0;i<s2.length();i++)b[i]=s2[s2.length()-i-1]-'0';
        int l=max(s1.length(),s2.length());
        int f=0;
        for (int i=0;i<l;i++)
        {
             c[i]=a[i]+b[i];
             if(f==1)c[i]+=1,f=0;
             if(c[i]>=10)c[i]-=10,f=1;
        }
        if(f==1)cout<<"1";
        for(int i=l-1;i>=0;i--)cout<<c[i];
        cout<<endl;
    }

    return 0;
}

七、奇偶校验

机试复试准备中--梦校(华科)真题_第7张图片
感觉这个就是模拟题!

#include

using namespace std;


int main()
{
   string s,ans="";
   cin>>s;
   int f;
   for(int i=0;i<s.length();i++)
   {
       int num=s[i];
       f=0,ans="";
       for(int j=6;j>=0;j--)
       {
           if ((1<<j)<=num)
           {
               ans+="1";
               f++;
                num-=1<<j;
           }
           else ans+="0";
       }
       if (f&1)cout<<0<<ans<<endl;
       else cout<<1<<ans<<endl;
   }

    return 0;
}

八、最大的两个数

机试复试准备中--梦校(华科)真题_第8张图片

#include

using namespace std;

int a[8][8];
int b[8][8];

int main()
{
   for(int i=0;i<4;i++)
    for(int j=0;j<5;j++)
    cin>>a[i][j];
    int ans1,ans2;
   for(int i=0;i<5;i++)
   {
       ans1=a[0][i],ans2=a[1][i];
        for (int j=2;j<4;j++)
   {
       if(a[j][i]>min(ans1,ans2))
       {
           if(ans1>ans2)ans2=a[j][i];
           else ans1=ans2,ans2=a[j][i];
       }
   }
   b[0][i]=ans1,b[1][i]=ans2;

   }
   for(int i=0;i<2;i++)
  {
        for (int j=0;j<5;j++)
   {
    cout<<b[i][j]<<" ";
   }
   cout<<endl;
  }
    return 0;
}

九、二叉树遍历(DFS)

机试复试准备中--梦校(华科)真题_第9张图片
这个很考察思维和字符串的使用。

#include

using namespace std;

void dfs(string pre,string in)
{
    if(pre.empty())return;
    char root=pre[0];
    int k=in.find(root);//查找这个根节点在哪个位置
    dfs(pre.substr(1,k),in.substr(0,k));
    dfs(pre.substr(k+1),in.substr(k+1));
    cout<<root;

}

int main()
{
    string pre,in;
    while(cin>>pre>>in)
    {
        dfs(pre,in);
        cout<<endl;
    }


    return 0;
}

十、成绩排序

#include 
using namespace std;

struct st{
string name;
int age;
int grade;
bool operator <(const st &x)const{
    //将学生数据按成绩从低到高排序,如果成绩相同则按姓名字符的字典序排序,如果姓名的字典序也相同则按照学生的年龄从小到大排序
  
    if(grade==x.grade&&name!=x.name) return name<x.name;
    if(grade==x.grade&&name==x.name) return age<x.age;
    return grade<x.grade;
}
};
st stu[1010];
int main()
{
    int t;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        cin>>stu[i].name>>stu[i].age>>stu[i].grade;
    }
    sort(stu,stu+t);
    for(int i=0;i<t;i++)
        {
            cout<<stu[i].name<<" "<<stu[i].age<<" "<<stu[i].grade<<endl;
        }
    return 0;
}

十一、守形数

机试复试准备中--梦校(华科)真题_第10张图片

#include

using namespace std;


int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if ((n*n)>=10&&n==(n*n)%10)
            printf("Yes!\n");
        else if((n*n)>=100&&n==(n*n)%100)
            printf("Yes!\n");
        else printf("No!\n");
    }
    return 0;
}

十二、矩阵最大值

机试复试准备中--梦校(华科)真题_第11张图片

#include

using namespace std;
const int N=105;
int a[N][N];

int main()
{
    int m,n,res,ans,sum;
    while(~scanf("%d%d",&m,&n))
    {
        for (int i=0; i<m; i++)
        {
            res=-1,ans=-1,sum=0;
            for(int j =0; j<n; j++)
            {
                scanf("%d",&a[i][j]);
                sum+=a[i][j];
                if(a[i][j]>ans)
                {
                    ans=a[i][j];
                    res=j;
                }
            }
            a[i][res]=sum;
        }
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<n; j++)
            {
                cout<<a[i][j]<<" ";
            }
            cout<<endl;
        }
    }

    return 0;
}

十三、最小年龄的3个职工(结构体排序)

机试复试准备中--梦校(华科)真题_第12张图片

#include

using namespace std;
const int N=35;
 struct node {
int num;
string name;
int age;
}p[N];

bool cmp(node x,node y)
{
    if(x.age!=y.age)
        return x.age<y.age;
    else if(x.num!=y.num)
        return x.num<y.num;
    else return x.name<y.name;
}


int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>p[i].num>>p[i].name>>p[i].age;
    }
    sort(p,p+n,cmp);
    for(int i=0;i<min(n,3);i++)
        cout<<p[i].num<<" "<<p[i].name<<" "<<p[i].age<<endl;
    return 0;
}

十四、对称矩阵

机试复试准备中--梦校(华科)真题_第13张图片

#include

using namespace std;
const int N=110;
int a[N][N];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int f=1;
        for(int i =0;i<n;i++)
            for (int j=0;j<n;j++)
            scanf("%d",&a[i][j]);
            for(int i=0;i<n;i++)
            for(int j=i+1;j<n;j++)
            if(a[i][j]!=a[j][i])
            {
                f=0;
                break;
            }
            if(f==1)
                printf("Yes!\n");
            else printf("No!\n");
    }


    return 0;
}

十五、A+B(读取问题)

机试复试准备中--梦校(华科)真题_第14张图片

#include

using namespace std;

int main()
{
    string A,B;

    while(cin>>A>>B)
    {
        int a=0,b=0,f=1;
        for(int i=0; i<A.length(); i++)
        {
            if(A[i]=='-')
            {
                f=-1;
                continue;
            }
            if(A[i]==',')
                continue;
            a=a*10+A[i]-'0';
        }
        a=f*a;
        f=1;
        for(int i=0; i<B.length(); i++)
        {
            if(B[i]=='-')
            {
                f=-1;
                continue;
            }
            if(B[i]==',')
                continue;
            b=b*10+B[i]-'0';
        }
        b=f*b;
        long long ans;
        ans=a+b;
        cout<<ans<<endl;
    }
    return 0;
}

十六、打印日期(闰年的判断)

机试复试准备中--梦校(华科)真题_第15张图片

写法一:for

#include

using namespace std;
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

int main()
{
    int y,d;
    while(cin>>y>>d)
    {
        int m=1,day=0;
        if(y%100!=0&&y%4==0||y%400==0)
                    month[2]=29;
                else month[2]=28;
        for(int i=0;i<d;i++)
        {
            day++;
            if(month[m]<day)
            {
                m++;
                day=1;
            }
        }
        printf("%04d-%02d-%02d\n",y,m,day);
    }
    return 0;
}

写法二:while更好

#include

using namespace std;
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

int main()
{
    int y,d;
    while(cin>>y>>d)
    {
        int m=1,day=0;
        if(y%100!=0&&y%4==0||y%400==0)
                    month[2]=29;
                else month[2]=28;
        for(int i=0;i<d;i++)
        {
            day++;
            if(month[m]<day)
            {
                m++;
                day=1;
            }
        }
        printf("%04d-%02d-%02d\n",y,m,day);
    }
    return 0;
}

十七、大数排序

机试复试准备中--梦校(华科)真题_第16张图片

#include

using namespace std;
const int N=110;
string a[N];
bool cmp(string x,string y)
{
    if(x.length()!=y.length())
        return x.length()<y.length();
    return x<y;
}

int main()
{
   int n;
   cin>>n;
   for(int i=0;i<n;i++)cin>>a[i];
   sort(a,a+n,cmp);
   for(int i=0;i<n;i++)cout<<a[i]<<endl;
    return 0;
}

二十、回文字符串

机试复试准备中--梦校(华科)真题_第17张图片

#include

using namespace std;

int main()
{
  string s;
  while(cin>>s)
  {
      int i=0,j=s.length()-1,f=1;
      while(i<j)
      {
          if (s[i]==s[j])i++,j--;
          else {
            f=0;
            break;
          }
      }
      if(f==0)cout<<"No!"<<endl;
      else cout<<"Yes!"<<endl;
  }
    return 0;
}

二十一、找位置(STL容器)

机试复试准备中--梦校(华科)真题_第18张图片

#include

using namespace std;

int main()
{
  string s;
  cin>>s;
  int len=s.length();
  map<char,vector<int>>a;
  map<char,int>b;
  for(int i=0;i<len;i++)a[s[i]].push_back(i);
  for(int i=0;i<len;i++)
  {
      int len=a[s[i]].size();
      if(len>1&&!b[s[i]])
      {
          for(int j=0;j<len;j++)
          {
              if(j==0)printf("%c:%d",s[i],a[s[i]][j]);
              else printf(",%c:%d",s[i],a[s[i]][j]);
          }
          b[s[i]]=1;
          cout<<endl;
      }
  }
    return 0;
}

二十二、阶乘

机试复试准备中--梦校(华科)真题_第19张图片

#include

using namespace std;

long long p[15];

int main()
{
  int n;
  cin>>n;
  p[1]=1;
  for(int i=2;i<=10;i++)
    p[i]=p[i-1]*i;
    int y1=0,y2=0;
    int t=1;
    while(t<=n&&t&1)
    {
        y1+=p[t];
        t+=2;
    }
    t=2;
     while(t<=n&&(t&1)==0)
    {
        y2+=p[t];
        t+=2;
    }
    cout<<y1<<" "<<y2;
    return 0;
}

二十三、八进制

机试复试准备中--梦校(华科)真题_第20张图片

#include

using namespace std;


int main()
{
  int n,ans=0,res=1;
  while(cin>>n)
  {
      while(n)
      {
          int x=n%8;
          ans=ans+x*res;
          res*=10;
          n/=8;
      }
      cout<<ans<<endl;
      ans=0;
      res=1;

  }
    return 0;
}

二十四、最长&最短文本(STL)

机试复试准备中--梦校(华科)真题_第21张图片

#include

using namespace std;

vector<int>len;

int main()
{
    unordered_map<int,vector<string>>a;
    string s;
    while(cin>>s)
    {
        a[s.size()].push_back(s);
        len.push_back(s.size());
    }
    sort(len.begin(),len.end());
    int hh=len[0],tt=len[len.size()-1];
    for(auto c:a[hh])
        cout<<c<<endl;
    for(auto c:a[tt])
        cout<<c<<endl;
    return 0;
}

二十五、梅森素数(素数)

机试复试准备中--梦校(华科)真题_第22张图片

#include

using namespace std;

bool is_prime(long long x)//判断是否为素数
{
    if(x<2)return false;
    for(long long i=2;i*i<=x;i++)
        if(x%i==0)return false;
    return true;
}

int main()
{
   long long n;
   cin>>n;
   long long x=2,c=1,cnt=1;
   while(c<=n)
   {
       if(is_prime(c))printf("M(%lld)=%lld\n",cnt,c);
       cnt++;
       x<<=1;
       c=x-1;
   }
    return 0;
}

二十六、单词个数统计

机试复试准备中--梦校(华科)真题_第23张图片

#include

using namespace std;

int a[30];

int main()
{
   string s;
   getline(cin,s);
   int ans1=0,ans2=1,f=0,_max=0;
   for(int i=0;i<s.size();i++)
   {
       if(s[i]==' '){f=1;continue;}
       if(f==1)ans2+=1,f=0;
       ans1+=1;
       a[tolower(s[i])-'a']+=1;
       _max=max(_max, a[tolower(s[i])-'a']);
   }
cout<<ans1<<endl<<ans2<<endl;

for(int i=0;i<26;i++)
{
    if(a[i]==_max)
    cout<<(char)('a'+i)<<" ";
}
cout<<endl<<_max;
    return 0;
}

二十七、进制转换(巧)

机试复试准备中--梦校(华科)真题_第24张图片

#include

using namespace std;
int h[35];
int main()
{
    string s;
    cin>>s;
    int l=s.size(),ans=0,t,x;
    t=pow(12,l-1);
    for(int i=0;i<l;i++)
    {
        if(s[i]>='a')x=s[i]-'a'+10;
        else x=s[i]-'0';
        cout<<x<<" ";
        ans+=t*x;
        t/=12;
    }
    cout<<endl<<ans<<endl;
    for(int i=0;i<=31;i++)//转换为二进制
    {
        h[i]=ans&1;
        ans>>=1;
    }
    for(int i=31,j=0;i>=0;i--)
    {
        cout<<h[i];
        j++;
        if(j==8)
        {
            cout<<" ";
            j=0;
        }
    }
    return 0;
}

二十八、排序去重

机试复试准备中--梦校(华科)真题_第25张图片

#include

using namespace std;

vector<int> a;
int main()
{
    int n,x;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x;
        a.push_back(x);
    }
    sort(a.begin(),a.end());
     for(int i=0;i<a.size();i++)
            cout<<a[i]<<" ";
            cout<<endl;
    for(int i=0;i<a.size();i++)
     {
         if(a[i]!=a[i+1])
            cout<<a[i]<<" ";
     }


    return 0;
}

二十九、十进制加密

机试复试准备中--梦校(华科)真题_第26张图片
这道题考察的是位运算,自己有些生疏了,可以做这道题熟络一下。

#include

using namespace std;

int a[]={0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1};
int b[]={1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0};
int c[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0};
int main()
{
   int n,x=0,e=0,p=0;
   cin>>n;
   for(int i=0;i<31;i++)
   {
       if((n&(1<<i))==0)continue;
       if(a[i]==1){x|=(1<<i);}
         if(b[i]==1){e|=(1<<i);}
           if(c[i]==1){p|=(1<<i);}
   }
    long long  ans=x+(e<<8)+(p>>24);
    cout<<ans;
    return 0;
}
//010011010010
//000011010000
//010000000010
//000000000000

三十、删除数字(贪心)

机试复试准备中--梦校(华科)真题_第27张图片
对于删数问题,可以采用贪心算法来求解。贪心算法即每次都选择当前最优的方案,从而得到全局最优解。对于这道题,可以使用如下的贪心策略:
从左往右扫描数字,找到第一个比自己右侧数字大的数字,将该数字删除;
如果没有找到这样的数字,说明所有数字都是递增的,直接删除最后一个数字;
重复上述过程,直到删除了k个数字为止。
注意前导0的删除

#include 
#include 
using namespace std;
 
int main()
{
    string n;  // 原始数字n
    int k;     // 需要删除的数字个数
    while (cin >> n >> k)
    {
        string res = "";   // 存储最终结果
        int len = n.size(); // 数字n的长度
 
        // 假如需要删除的数字个数大于等于数字n的长度,直接输出0
        if (k >= len)
        {
            cout << 0 << endl;
            continue;
        }
 
        int cnt = 0;  // 记录已经删除的数字个数
        for (int i = 0; i < len; i++)
        {
            while (cnt < k && !res.empty() && res.back() > n[i])
            {
                // 如果需要删除的数字尚未全部删除,且新来的数字比当前的倒数第一个数字小
                // 就把最后一个数字删除,并将已删除数字个数加1
                res.pop_back();
                cnt++;
            }
            res.push_back(n[i]);  // 将新的数字添加到结果字符串中
        }
 
        // 如果需要删除的数字还没删除完,再从结果字符串末尾删除
        while (cnt < k)
        {
            res.pop_back();
            cnt++;
        }
 
        // 去掉前导零,并输出结果
        int i = 0;
        while (i < res.size() && res[i] == '0') i++;
        if (i == res.size()) cout << 0 << endl;
        else cout << res.substr(i) << endl;
    }
    return 0;
}

你可能感兴趣的:(2023,算法,c++)