【华为机试在线训练】Day5

题目描述

信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。  

采集输入大数据和分类规则,通过大数据分类处理程序,将大数据分类输出。

输入描述:

一组输入整数序列I和一组规则整数序列R,I和R序列的第一个整数为序列的个数(个数不包含第一个整数);整数范围为0~0xFFFFFFFF,序列个数不限

输出描述:

从R依次中取出R<i>,对I进行处理,找到满足条件的I<j>: 

I<j>整数对应的数字需要连续包含R<i>对应的数字。比如R<i>为23,I<j>为231,那么I<j>包含了R<i>,条件满足 。 

按R<i>从小到大的顺序:

(1)先输出R<i>; 

(2)再输出满足条件的I<j>的个数; 

(3)然后输出满足条件的I<j>在I序列中的位置索引(从0开始); 

(4)最后再输出I<j>。 

附加条件: 

扫描二维码关注公众号,回复: 2524275 查看本文章

(1)R<i>需要从小到大排序。相同的R<i>只需要输出索引小的以及满足条件的I<j>,索引大的需要过滤掉 

(2)如果没有满足条件的I<j>,对应的R<i>不用输出 

(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)

序列I:15,123,456,786,453,46,7,5,3,665,453456,745,456,786,453,123(第一个15表明后续有15个整数) 

序列R:5,6,3,6,3,0(第一个5表明后续有5个整数) 

输出:30, 3,6,0,123,3,453,7,3,9,453456,13,453,14,123,6,7,1,456,2,786,4,46,8,665,9,453456,11,456,12,786

说明:

30----后续有30个整数

3----从小到大排序,第一个R<i>为0,但没有满足条件的I<j>,不输出0,而下一个R<i>是3

6--- 存在6个包含3的I<j> 

0--- 123所在的原序号为0 

123--- 123包含3,满足条件 

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
bool match(int m,int n)
{
    string str1=to_string(m);
    string str2=to_string(n);
    int pos=str2.find(str1);
    if(pos!=-1)
        return true;
    else
        return false;
}
int main()
{
    int m,n;
    while(cin>>m)
    {
        vector<int> I;
        vector<int> R;
        for(int i=0;i<m;i++)
        {
            int  temp;
            cin>>temp;
            I.push_back(temp);          
        }
        cin>>n;
        for(int i=0;i<n;i++)
        {
            int  temp;
            cin>>temp;
            R.push_back(temp);          
        }
        sort(R.begin(),R.end());//排序
        R.erase(unique(R.begin(), R.end()), R.end());//去重
          
        vector<int> index;
        vector<int> value;
        vector<int> cnt;
        vector<int> index1;
        for(int i=0;i<R.size();i++)
        {
            int cnt1=0;//每个R[i]在I中存在的个数
            for(int pos=0;pos<I.size();pos++)//遍历I
            {              
                if(match(R[i],I[pos]))//如果R[i]在I中
                {
                    cnt1++;//计数++
                    index.push_back(pos);//把相应位置压入index
                    value.push_back(I[pos]);//把在I中相应位置的值压入value
                }
            }
            if(cnt1!=0)//判断每个R[i]在I中的个数是否为0
            {
                cnt.push_back(cnt1);//把R[i]在I中对应找到的个数压入cnt
                index1.push_back(i);//把R中每个位置压入index1
            }  
        }        
        int j=0;
        cout<<2*index.size()+index1.size()+cnt.size()<<' ';//2*index.size()是一个位置+位置的值
        for(int i=0;i<cnt.size();i++)
        {
            cout<<R[index1[i]]<<' '<<cnt[i]<<' '; //把R中相应的值和在I中找到的个数输出    
            while(cnt[i]-->0)//循环输出R中R[i]在I中的位置和值
            {
                cout<<index[j]<<' '<<value[j];
                if(i==cnt.size()-1&&cnt[i]==0)
                {
                   cout<<endl;
                }   
                else
                {
                    cout<<' ';
                }   
                j++;
            }
        }
    }
    return 0;
}


题目描述

编写一个程序,将输入字符串中的字符按如下规则排序。

规则 1 :英文字母从 A 到 Z 排列,不区分大小写。

       如,输入: Type   输出: epTy

规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。

     如,输入: BabA   输出: aABb

规则 3 :非英文字母的其它字符保持原来的位置。

     如,输入: By?e   输出: Be?y

样例:

    输入:

   A Famous Saying: Much Ado About Nothing(2012/8).

    输出:

   A  aaAAbc   dFgghh :  iimM   nNn   oooos   Sttuuuy  (2012/8).

#include<vector>
#include<iostream>
#include<string>
 
using namespace std;
 
int main()
{
    string s;
    vector<char> tempChar;
    while(getline(cin,s))
    {
        tempChar.clear();
        int len = s.size();
        for(int j=0; j<26; j++)
        {
            for(int i=0; i<len; i++)
            {
                if(s[i]-'a'==j||s[i]-'A'==j)
                {
                    tempChar.push_back(s[i]);
                }
            }
        }
        for(int i=0,k=0;(i<len)&&k<tempChar.size();i++)
        {
            if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z'))
                s[i]=tempChar[k++];
        }
        cout<<s<<endl;
    }
    return 0;
}


输入描述:

先输入字典中单词的个数,再输入n个单词作为字典单词。
输入一个单词,查找其在字典中兄弟单词的个数
再输入数字n

输出描述:

根据输入,输出查找到的兄弟单词的个数

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
bool isBrother(string str, string s){   
    if(str.size() == s.size()){
        if(str == s)
            return false;
        sort(str.begin(), str.end());
        sort(s.begin(), s.end());
        if(str == s)
            return true;
    }
    return false;
}
int main(){
    int num;
    while(cin >> num){
        string str;
        string word,s;
        int index;
        vector<string> vs;
        for(int i = 0; i < num; ++i){
            cin >> str;
            vs.push_back(str);
        } 
        sort(vs.begin(), vs.end());  // 因为是字典,一定要排序!!
        cin >> word;
        cin >> index;
        int counts = 0;
         
        for(int i = 0; i < num; ++i){
            if(isBrother(word, vs[i])){
                counts ++;
                if(counts == index)
                    s = vs[i];
            }
        }
        if(!vs.empty())
            cout << counts << endl;
        if(counts >= index)
            cout << s << endl; 
        
    }
    return 0;
}


题目描述

题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。

输入:

有一个正偶数N(N≤100),表示待挑选的自然数的个数。后面给出具体的数字,范围为[2,30000]。

输出:

输出一个整数K,表示你求得的“最佳方案”组成“素数伴侣”的对数。

输入描述:

输入说明
1 输入一个正偶数n
2 输入n个整数

输出描述:

求得的“最佳方案”组成“素数伴侣”的对数。

不会做看大佬。。。https://www.nowcoder.com/profile/3278739/codeBookDetail?submissionId=12795039

#include <iostream>
#include <cstring>
#include <vector>
 
using namespace std;
vector<int> G[105];
int pre[105];
bool used[105];
 
bool dfs(int k)
{
    for(int i=0;i<G[k].size();++i)
    {
        if(used[G[k][i]] == 0)
        {
            used[G[k][i]] = 1;
            if(pre[G[k][i]] == 0 || dfs(pre[G[k][i]]))
            {
                pre[G[k][i]]=k;
                return true;
            }
        }
        else
            continue;
    }
    return false;
}
 
int main()
{
    bool isprime[80000];
    memset(isprime,1,sizeof(isprime));
    isprime[0]=0;//数据从2开始的
    isprime[1]=0;
    for(int i=4;i<80000;i+=2)//除了2以外所有的偶数都不是质数
        isprime[i]=0;
    for(int i=3;i*i<80000;i+=2)
        if(isprime[i])
            for(int j=i*i;j<80000;j+=2*i)
                isprime[j]=0;
    int N;
    int nums[105];
    int temp;
     
    while(cin>>N)
    {
        for(int i=1;i<=N;++i)
        {
            cin>>temp;
            nums[i]=temp;
        }
        //匹配规则
        for(int i=1;i<=N;++i)
        {
            for(int j=i+1;j<=N;++j)
            {
                if(isprime[nums[i]+nums[j]])
                    (nums[i]&1)?G[i].push_back(j):G[j].push_back(i);
            }
        }
        memset(pre,0,sizeof(pre));
        int count=0;
        for(int i=1;i<=N;++i)
        {
            memset(used,0,sizeof(used));
            if(dfs(i))
                count++;
        }
        cout<<count<<endl;
        for(int i=1;i<=N;++i)
            G[i].clear();
    }
    return 0;
}
添加笔记


题目描述

1、对输入的字符串进行加解密,并输出。

2加密方法为:

当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;

当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;

其他字符不做变化。

3、解密方法为加密的逆过程。

接口描述:

    实现接口,每个接口实现1个基本操作:

void Encrypt (char aucPassword[], char aucResult[]):在该函数中实现字符串加密并输出

说明:

1、字符串以\0结尾。

2、字符串最长100个字符。

int unEncrypt (char result[], char password[]):在该函数中实现字符串解密并输出

说明:

1、字符串以\0结尾。

2、字符串最长100个字符。

输入描述:

输入说明
输入一串要加密的密码
输入一串加过密的密码

输出描述:

输出说明
输出加密后的字符
输出解密后的字符

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
 
const string helper1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const string helper2 = "BCDEFGHIJKLMNOPQRSTUVWXYZAbcdefghijklmnopqrstuvwxyza1234567890";
void Encrypt(string str){
    string res;
    for (int i = 0; i < str.size(); i++) { 
        res += helper2[helper1.find(str[i])];  
    }   
    cout << res << endl;       
}
void unEncrypt(string str){
    string res;
    for (int i = 0; i < str.size(); i++) { 
        res += helper1[helper2.find(str[i])];   
    }       
    cout << res << endl;    
}
int main(){
    string str1, str2;
    while(getline(cin, str1)){
        getline(cin, str2);
        Encrypt(str1);
        unEncrypt(str2);
    }
    return 0;
}


题目描述

按照指定规则对输入的字符串进行处理。

详细描述:

将输入的两个字符串合并。

对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标意思是字符在字符串中的位置。

对排序后的字符串进行操作,如果字符为‘0’——‘9’或者‘A’——‘F’或者‘a’——‘f’,则对他们所代表的16进制的数进行BIT倒序的操作,并转换为相应的大写字符。如字符为‘4’,为0100b,则翻转后为0010b,也就是2。转换后的字符为‘2’; 如字符为‘7’,为0111b,则翻转后为1110b,也就是e。转换后的字符为大写‘E’。

举例:输入str1为"dec",str2为"fab",合并为“decfab”,分别对“dca”和“efb”进行排序,排序后为“abcedf”,转换后为“5D37BF”

接口设计及说明:

/*

功能:字符串处理

输入:两个字符串,需要异常处理

输出:合并处理后的字符串,具体要求参考文档

返回:无

*/

void ProcessString(char* str1,char *str2,char * strOutput)

{

}

输入描述:

输入两个字符串

输出描述:

输出转化后的结果

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const string helper1 = "0123456789abcdefABCDEF";
const string helper2 = "084C2A6E195D3B7F5D3B7F";
int main()
{
    string s1,s2,s;
    while(cin >> s1 >> s2)
    {
        s = s1 + s2;
        string str1,str2,str;
        for(int i = 0;i < s.length();i++)
        {
            if(i % 2 == 0)
                str1 += s[i];
            else
                str2 += s[i];
        }
        sort(str1.begin(),str1.end());
        sort(str2.begin(),str2.end());
        for(int i = 0;i < s.length();i++)
        {
            if(i % 2 == 0)
                str += str1[i/2];
            else
                str += str2[i/2];
        }
        for(int i = 0;i < str.length();i++)
        {
            int n = helper1.find(str[i]);
                if(n != -1)
                    str[i] = helper2[n];
        }
        cout << str << endl;
    }
    getchar();
    return 0;
}


题目描述

对字符串中的所有单词进行倒排。

说明:

1、每个单词是以26个大写或小写英文字母构成;

2、非构成单词的字符均视为单词间隔符;

3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

4、每个单词最长20个字母;

输入描述:

输入一行以空格来分隔的句子

输出描述:

输出句子的逆序

#include <stdio.h>
#include <string.h>
 
int main(void){
    char str[10000];
    while(gets(str)){
        int len=strlen(str),i,j;
        //计算空格
        int flag=0;
        if((str[0]>='a'&&str[0]<='z')||(str[0]>='A'&&str[0]<='Z'))flag=0;
        else flag=1;
        for(i=len-1;i>=(0+flag);i--){
            int word_len=0;
            while((str[i]>='a'&&str[i]<='z')||(str[i]>='A'&&str[i]<='Z')){
                i--;
                word_len++;
                if(i==(-1+flag))break;
            }
            for(j=1;j<=word_len;j++){
                printf("%c",str[i+j]);
                if(j==word_len){
                     if(i==(-1+flag)){
                        printf("\n");
                        break;
                    }
                    printf(" ");   
                }
            }
            
        } 
    }
    return 0;
}


题目描述

Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

输入描述:

输入一个字符串

输出描述:

返回有效密码串的最大长度

//回文?

/*
思路:以某个元素为中心,向两边扩展,分别计算
偶数长度的回文最大长度和奇数长度的回文最大长度。
时间复杂度O(n^2) 
*/
#include<iostream>
#include <string>
using namespace std;
 
int main(){
    string s;
    while(cin>>s){
        const int len = s.size();
        if(len <= 1) return -1;
        int maxLen = 0;
        for(int i = 1; i < len; i++){
            //寻找以i-1,i为中点偶数长度的回文
            int low = i-1, high = i;
            while(low >= 0 && high < len && s[low] == s[high]){
                 low--; high++;
            }
            if(high - low - 1 > maxLen)
               maxLen = high - low -1;
            //寻找以i为中心的奇数长度的回文
            low = i- 1; high = i + 1;
            while(low >= 0 && high < len && s[low] == s[high]){
                low--; high++;
            }
            if(high - low - 1 > maxLen)
               maxLen = high - low -1;
        }
        cout<<maxLen<<endl;
    }
    return 0;
}


题目描述

原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字             相对应的二进制数
10                   00001010
0                    00000000
3                    00000011
193                  11000001
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。

的每段可以看成是一个0-255的整数,需要对IP地址进行校验

输入描述:

输入 
1 输入IP地址
2 输入10进制型的IP地址

输出描述:

输出
1 输出转换成10进制的IP地址
2 输出转换后的IP地址

#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
  
using namespace std;
  
void  convert_to_binary(int num, vector<int> &B_vec){
    vector<int> result;
    for(int i=0;i<8;++i){
        int a=num%2;
        int b=num/2;
        num=b;
        result.push_back(a);
    }
    for(int i=7;i>=0;--i){
        B_vec.push_back(result[i]);
    }
   
}
  
void  convert_to_binary1(long long  num, vector<int> &B_vec){
    vector<int> result;
    for(int i=0;i<32;++i){
        int a=num%2;
        long long b=num/2;
        num=b;
        result.push_back(a);
    }
    for(int i=31;i>=0;--i){
        B_vec.push_back(result[i]);
    }
   
}
  
  
int main(){
      
    string ip;
      
    long long a_num;
    while(cin>>ip){
        cin>>a_num;
          
        //1、IP地址到整数值
        long long sum=0;
        int b=0,len;
        vector<int> nums;
        for(int j=0;j<ip.size();++j){
            if(ip[j]=='.'){
                len=j-b;
                string str=ip.substr(b,len);
                int num=atoi(str.c_str());
                nums.push_back(num);
                b=j+1;
              
            }
            else if(j==ip.size()-1){
                len=j-b+1;
                string str=ip.substr(b,len);
                int num=atoi(str.c_str());
                nums.push_back(num);
                  
            }
          
        }
        vector<int> temp;
        for(int i=0;i<nums.size();++i){
            if(nums[i]<0||nums[i]>255)
                cout<<"IP is invalid!"<<endl;
            else{
                convert_to_binary(nums[i], temp);
            }
        }
        for(int j=temp.size()-1,k=0;j>=0;--j){
            sum+=temp[j]*pow(2,k);
            k++;
        }
        cout<<sum<<endl;
          
        //2、整数值到IP地址
        vector<int> temp1;
        convert_to_binary1(a_num,temp1);
      
        vector<int> temp2;
        vector<int> temp3;
        for(int i=0;i<32;++i){
            temp2.push_back(temp1[i]);
            if((i+1)%8==0){
                int sum1=0;
                for(int i=0,k=temp2.size()-1;i<temp2.size();++i,k--){
                    sum1+=temp2[i]*pow(2,k);
                }
                temp3.push_back(sum1);
                temp2.clear();
            }
        }
        cout<<temp3[0]<<"."<<temp3[1]<<"."<<temp3[2]<<"."<<temp3[3]<<endl;
    }
  
    return 0;
      
}


题目描述

Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过C语言解决。

输入描述:

Lily使用的图片包括"A"到"Z"、"a"到"z"、"0"到"9"。输入字母或数字个数不超过1024。

输出描述:

Lily的所有图片按照从小到大的顺序输出

#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
 
using namespace std;
 
 
int main(){
    string s;
    while(cin>>s){
        sort(s.begin(),s.end());
        cout<<s<<endl;
    }
     
     
    return 0;
}

猜你喜欢

转载自blog.csdn.net/HelloZEX/article/details/81355418