算法学习——华为机考题库7(HJ41 - HJ45)

算法学习——华为机考题库7(HJ41 - HJ45)

HJ41 称砝码

描述

现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ;
每种砝码对应的数量为 x1,x2,x3…xn 。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。

注:

称重重量包括 0

数据范围:每组输入数据满足 1≤n≤10 , 1≤m ≤2000 , 1≤x i ≤10
输入描述:
对于每组测试数据:
第一行:n — 砝码的种数(范围[1,10])
第二行:m1 m2 m3 … mn — 每种砝码的重量(范围[1,2000])
第三行:x1 x2 x3 … xn — 每种砝码对应的数量(范围[1,10])
输出描述:
利用给定的砝码可以称出的不同的重量数

示例

在这里插入图片描述

代码解析

#include <iostream>
#include <set>
#include <vector>
using namespace std;



int main() {
    int N;
    cin>>N;
    vector<int> weight;
    vector<int> num;
    vector<int> block;
    
    int tmp;
    for(int i=0 ; i<N ;i++)
    {
        cin>>tmp;
        weight.push_back(tmp);
    }
    
    for(int i=0 ; i<N ;i++)
    {
        cin>>tmp;
        num.push_back(tmp);
    }

    for(int i=0 ; i<N ;i++)
    {   
        while(num[i]--)
            block.push_back(weight[i]);
    }
    set<int> myset;
    myset.insert(0);
    for(int i=0 ; i<block.size() ;i++)
    {
        set<int> myset2(myset);

        for(auto it:myset2)
            myset.insert(it + block[i]);
        

    }

    // for(auto it:myset)
    //     cout<<it<<' ';

    cout<<myset.size()<<endl;

}
// 64 位输出请用 printf("%lld")

HJ42 学英语

描述

Jessi初学英语,为了快速读出一串数字,编写程序将数字转换成英文:

具体规则如下:
1.在英语读法中三位数字看成一整体,后面再加一个计数单位。从最右边往左数,三位一单位,例如12,345 等
2.每三位数后记得带上计数单位 分别是thousand, million, billion.
3.公式:百万以下千以上的数 X thousand X, 10亿以下百万以上的数:X million X thousand X, 10 亿以上的数:X billion X million X thousand X. 每个X分别代表三位数或两位数或一位数。
4.在英式英语中百位数和十位数之间要加and,美式英语中则会省略,我们这个题目采用加上and,百分位为零的话,这道题目我们省略and

下面再看几个数字例句:
22: twenty two
100: one hundred
145: one hundred and forty five
1,234: one thousand two hundred and thirty four
8,088: eight thousand (and) eighty eight (注:这个and可加可不加,这个题目我们选择不加)
486,669: four hundred and eighty six thousand six hundred and sixty nine
1,652,510: one million six hundred and fifty two thousand five hundred and ten

说明:
数字为正整数,不考虑小数,转化结果为英文小写;
保证输入的数据合法
关键字提示:and,billion,million,thousand,hundred。

数据范围: 1≤n≤2000000

输入描述:
输入一个long型整数

输出描述:
输出相应的英文写法

示例

在这里插入图片描述

代码解析

#include <iostream>
#include <string>
#include <vector>
using namespace std;


vector<string> other = {"zero", "one", "two", "three", "four", "five", "six", "seven",
                        "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
                           "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};

vector<string> ften = {"none", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
                        "seventy", "eighty", "ninety"};

string englishnum(long num)
{
    if(num >= 0 && num <= 19) return other[num];
    else if(num>=20 && num<=99)
    {
        if(num%10 == 0) return ften[num/10];
        else  return ften[num/10]+" "+englishnum(num%10);
    } 
    else if(num>=100 && num<=999) 
    {
        if(num%100 == 0) return other[num/100]+" hundred";
        else return englishnum(num/100)+" hundred and "+ englishnum(num%100);
    }
    else if(num>=1000 && num<=999999) 
    {
        if(num%1000 == 0) return englishnum(num/1000)+" thousand";
        else return englishnum(num/1000)+" thousand "+englishnum(num%1000);
    }
    else if(num>=1000000&&num<=999999999)
    {
        if(num%1000000==0) return englishnum(num/1000000)+" million";
        else return englishnum(num/1000000)+" million "+englishnum(num/1000%1000)+" thousand "+englishnum(num%1000);
    }
    else if(num>=1000000000)
    {
        if(num%1000000000==0) return other[num/1000000000]+" billion";
        else return englishnum(num/1000000000)+" billion "+englishnum(num%10000000/1000000)+ 
            " million "+englishnum(num%1000000/1000)+" thousand "+englishnum(num%1000);
    }
    return "";

}

int main() 
{
    long num;
    cin>>num;
    cout<<englishnum(num)<<endl;
}
// 64 位输出请用 printf("%lld")

HJ43 迷宫问题

描述

定义一个二维数组 N*M ,如 5 × 5 数组下所示:

int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。

数据范围: 2≤n,m≤10 , 输入的内容只包含 0≤val≤1

输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述:
左上角到右下角的最短路径,格式如样例所示。

示例

在这里插入图片描述
在这里插入图片描述

代码解析

#include <climits>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

int n,m;
int fornt[4][2] = {-1,0,1,0,0,-1,0,1};
vector<vector<vector<int>>> result2;

void dfs(vector<vector<int>> &date , vector<vector<bool>> &path , vector<vector<int>> &result , int x , int y)
{
    if(path[x][y] == true) return;
    path[x][y] = true;
    
    if(date[x][y] == 1) return;
    
    if(x == n-1 && y == m-1) result2.push_back(result);
    

    int new_x , new_y;
    for(int i=0 ; i < 4 ; i++)
    {
        new_x = x + fornt[i][0];
        new_y = y + fornt[i][1];
       
        if( new_x < 0 || new_x >= n || new_y < 0 || new_y >= m) continue;
       
        result.push_back({new_x,new_y});
        dfs(date,path,result,new_x,new_y);
        result.pop_back();
    }
    return ;

}

int main() {
    int tmp;
    cin>>n>>m;
    vector<vector<int>> date(n,vector<int>(m,0));
    vector<vector<int>> result;
   
    vector<vector<bool>> path(n,vector<bool>(m,false));
    for(int i=0 ; i<n ; i++)
    {
        for(int j=0 ; j<m ; j++)
        {
            cin>>tmp;
            date[i][j] = tmp;
        }
    }

    result.push_back({0,0});
    dfs(date,path,result,0,0);

    
    pair<int, int> minResult = {INT_MAX,INT_MAX};
    for(int i=0 ; i<result2.size() ; i++)
    {
        if(result2[i].size() < minResult.second) 
        {
            minResult.first = i;
            minResult.second = result2[i].size();
        }
    }

    for(int i=0 ; i< minResult.second ; i++)
    {
        cout<<'('<<result2[minResult.first][i][0]<<","<<result2[minResult.first][i][1]<<")"<<endl;
    }







}
// 64 位输出请用 printf("%lld")

HJ44 Sudoku

描述

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。
例如:
输入
在这里插入图片描述
输出
在这里插入图片描述
数据范围:输入一个 9*9 的矩阵
输入描述:
包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:
完整的9X9盘面数组

示例

在这里插入图片描述

代码解析

#include <iostream>
#include <set>
#include <vector>
using namespace std;

bool flag = false;

bool cheack(vector<vector<int>> &date , int x , int y ,int value)
{
    //行
    for(int j=0 ; j<9 ; j++)
    {
        if(  date[x][j]  == value ) return false; 
    }

     //列
    for(int j=0 ; j<9 ; j++)
    {
        if( date[j][y] == value) return false; 
      
    }

    //块
    int newx = x - x%3;
    int newy = y - y%3;
    for(int n = newx ; n < newx + 3 ; n++)
    {
        for(int m = newy ; m < newy + 3 ; m++)
        {
            if( date[n][m] == value) return false; 
            
        }
    }
  
    return true;
}

void dfs(vector<vector<int>> &date , int x , int y)
{
    //cout<<x<<' '<<y<<" date:"<<date[x][y]<<endl;
    
    if(date[x][y] != 0)
    {
        if(x==8 && y==8) 
        {
            flag = true;
            return;
        }

        if(y != 8) dfs(date,x,y+1);
        else dfs(date,x+1,0);

        return;
    }
    // cout<<x<<' '<<x<<' '<<date[x][y]<<endl;
    for(int i=1 ; i<=9 ; i++)
    {
     
        if(cheack(date, x, y, i) == true) 
        {
            date[x][y] = i;

           if(x==8 && y==8)
            {
                flag = true;
                return;
            }
            
            if(y != 8) dfs(date,x,y+1);
            else dfs(date,x+1,0);

            if(flag == false) date[x][y] = 0;
        }
    }

}

int main() {
    vector<vector<int>> date(9,vector<int>(9,0));
    
    int tmp;
    for(int i=0 ; i<9 ;i++)
    {
        for(int j=0 ; j<9 ;j++)
        {
            cin>>tmp;
            date[i][j] = tmp;
        }
    }


    dfs(date, 0, 0);


    for(int i=0 ; i<9 ;i++)
    {
        for(int j=0 ; j<9 ;j++)
        {
            cout<<date[i][j]<<' ';
        }
        cout<<endl;
    }


    
}
// 64 位输出请用 printf("%lld")

HJ45 名字的漂亮度

描述

给出一个字符串,该字符串仅由小写字母组成,定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。
每个字母都有一个“漂亮度”,范围在1到26之间。没有任何两个不同字母拥有相同的“漂亮度”。字母忽略大小写。

给出多个字符串,计算每个字符串最大可能的“漂亮度”。

本题含有多组数据。

数据范围: 输入的名字长度满足 1≤n≤10000

输入描述:
第一行一个整数N,接下来N行每行一个字符串

输出描述:
每个字符串可能的最大漂亮程度

示例

在这里插入图片描述

代码解析

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
using namespace std;

int beatiful(string &str)
{
    map<char, int> mymap;
    for(auto it:str)
        mymap[it]++;
    
    vector<pair<char,int>> vec(mymap.begin() , mymap.end());

    sort(vec.begin(), vec.end() , [](pair<char, int> &p1 , pair<char, int> &p2){return p1.second > p2.second;});
    
    int value = 26;
    for(int i=0 ; i<vec.size() ; i++)
    {
        vec[i].second = value;
        value--;
    }

    int result = 0;
    for(auto it:str)
    {
        for(auto it2 : vec)
        {
            if(it == it2.first) 
            {
                result += it2.second;
                break;
            }
        }
    }
    

    return result;

}

int main() {
    int N;
    cin>>N;
    vector<string> date;
    string tmp;
    while(N--)
    {
        cin>>tmp;
        date.push_back(tmp);
    }

    for(auto it:date)
        cout<<beatiful(it)<<endl;

}
// 64 位输出请用 printf("%lld")
  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉依达不拉胯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值