笔试模拟 day2

 观前提醒:

笔试所有系列文章均是记录本人的笔试题思路与代码,从中得到的启发和从别人题解的学习到的地方,所以关于题目的解答,只是以本人能读懂为目标,如果大家觉得看不懂,那是正常的。如果对本文的某些知识有不同的观点,欢迎讨论。

题目链接:

第一题:牛牛的快递_牛客题霸_牛客网

第二题:最小花费爬楼梯_牛客题霸_牛客网

第三题:数组中两个字符串的最小距离_牛客题霸_牛客网

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

第一题

思路:

本题就是一道简单的模拟题,可能存在的较难点是,如何将小数向上取整,这里有两种方法

1)使用c语言自带的ceil函数,它的功能就是向上取整,但是一般情况下,很难想到。

2)将浮点数转换为整型,然后再与原始值相减,观察结果。 

代码: 

//ceil库函数版本
#include <iostream>
#include <cmath>
using namespace std;

int main() {
   double a=0;
   char b;
   cin>>a>>b;
   int coin=0;
   if(a>1)
   {
    coin+=(20+ceil(a-1));
   } 
   else {
    coin+=20;
   }
    if(b == 'y') coin+=5;
    printf("%d\n",coin);
   return 0;
}

//使用类型强转版本
#include <iostream>
#include <cmath>
using namespace std;

int main() {
   double a=0;
   char b;
   cin>>a>>b;
   int coin=0;
    coin+=20; //因为a一定大于0,一定要加上这20元。
   if(a>1)
   {
        double c=a-1;
        if(c >(int)c) coin+=((int)c+1);
        else
        coin+=(c);
   } 
    if(b == 'y') coin+=5;
    printf("%d\n",coin);
   return 0;
}

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

第二题 

        

思路: 

题目第一眼,一道简单的动态规划题,可能最需要解释的是题意,题目要求到达楼顶,说明走过了所有的台阶,所以要返回到达n+1台阶后的花费的价钱。

状态表示:一个一维的dp表,表中内容为:到现在的台阶,花费的最小价格。

状态转移方程:假如现在求dp[n],dp[n]只能由dp[n-2]和dp[n-1]跳上来,两种跳上来的方案选择价格最少的就好了,需要注意的是跳上来的同时还要考虑本次起跳的花费

代码: 

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

int main() {
    int n=0;
    cin>>n;
    vector<int> cost(n),dp(n+1,0);
    //dp[n]就是跳过所有的台阶,到达的楼顶。
    for(int i=0;i<n;i++)
    { 
        int x=0;
        cin>>x;
        cost[i]=x;
    }
    for(int i=2;i<=n;i++)
    {
        dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
    }
    printf("%d\n",dp[n]);
    return 0;
}

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

 

第三题

        思路: 

1)暴力枚举

看到题目的反映是,求距离那就要考虑数组的下标,求下标的最简单方法是,双重遍历考虑所有的情况,但是时间复杂度太高,为O(n2),面对最高到10^5的数据要超时,那我们就要想其他办法。

2)贪心

我们想到我们可以通过哈希表记录下所有的目标字符的下标,但是通过示例二发现数组中可能有多个目标字符,所有要使用int数组记录所有的下标,然后再遍历哈希表。

但是我们又想到,既然已经要使用两个元素大小的哈希表,为啥不直接选择两个变量记录下标呢?每次下标更新,就更新距离(这就演变成了贪心,贪婪的地方在于我们每次考虑距离的时候,只是考虑前面的目标产生的距离)。

想要求的距离最短,所以选择min函数,因此要将记录距离的变量初始化一个较大的值。

        代码: 

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

int main() {
   int ret=0x3f3f3f3f;
//对应下面的min函数
   int len=0;
   cin>>len;
//这里没有必要真的记录下字符数组,反正也只是考虑数组的下标关系
   if(len == 1 ) 
   {
    printf("-1\n"); 
    return 0;
   }
   string str1="",str2="";
   cin>>str1>>str2;
   int cur1=-1,cur2=-1;
    //将记录目标字符的初始下标设为-1,是为了防止目标字符不在字符数组当中。
    //当然也是为了保证ret记录的距离是有效值。
   string str3=""; 
   for(int i=0;i<len;i++)
   {
        cin>>str3;
        if(str3 == str1) 
             cur1=i;
        if(str3 == str2) 
            cur2=i;
        if(cur2 != cur1 && cur1 != -1 && cur2 != -1) 
        {
            ret=min(ret,abs(cur2-cur1));
        }
        // printf("1\n");
   }
    //特殊判断,如果目标字符不在字符数组当中
   printf("%d\n",ret == 0x3f3f3f3f ?-1:ret);
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值