迅雷2010校园招聘四川大学第二次笔试答案

第三题找不到很好的解决方案。搜索+剪枝但感觉复杂度太吓人;DP状态太多,内存会爆掉;数学方法 ---- 整数拆分,想不出怎么拆;... 。等候大牛们指点迷津。

   感觉这次的试题有一定难度,也很繁琐。

 

1,实现void strtol(char* num_str,char** endptr,int base)函数,此函数的功能是将一个字符串num_str转换成整数。num_str中保存的是待转换的字符串。字符串有8,10,16进制三种形式,保存在base参数中,若base为0,则需要自己判断具体的进制。要判断是否溢出,若为上溢出,返回INT_MAX,若为下溢出,返回INT_MIN。字符串num_str可能存在非法字符,若存在非法字符,返回非法字符前面的转换结果,并将endptr指向第一个非法字符,若没有非法字符,不需要返回endptr。

#注:不能使用任何库函数。
思路:在 base == 0 时判断进制,读数时注意非法字符,就这两点。

程序:

#include <iostream>
using namespace std;

/*
 * 判断进制
 * 1. num_str中的字符都不大于 '7' 则返回 8 进制
 * 2. num_str中的字符都不大于 '9' 则返回 10 进制
 * 3. 返回 16 进制
 */

int find_base(char *num_str)
{
  char c = '0';
  for (char *temp = num_str; *temp != '/0'; ++temp)
  {

    if ((*temp >= '0' && *temp <= '9') 
       || (*temp >= 'a' && *temp <= 'f') || (*temp >= 'A' && *temp <= 'F'))
    {
      c = (*temp > c ? *temp: c);
    }
    else
    {
      break;
    }
  }

  

  if (c <= '7')   return 8;
  else if (c <= '9')  return 10;
 
  return 16;
}

bool check(char c, int base)
{
  switch(base)
  {
    case 8:
      return (c >= '0' && c <= '7');
    case 10:
      return (c >= '0' && c <= '9');

    case 16:
      return ((c >= '0' && c <= '9') || (c >= 'a' && c <'f')
             || (c >= 'A' && c <= 'F'));
    default:
      return false;

  }
  return false;
}

int char_to_int(char c, int base)
{
  if (base <= 10 || c <= '9')
    return (c - '0');

  if ((c >= 'a' && c <= 'f') ) 
    return (c - 'a' + 10);
 
  return (c - 'A' + 10);
}

int str_to_int(char *num_str, char **endptr, int base)
{
  __int64 sum = 0;
  int     sign = 1;

  if (num_str[0] == '-')
  {
    sign = -1;
    ++num_str;

  }
 
  for (; *num_str != '/0'; ++num_str)
  {
    if (!check(*num_str, base))
    {
      *endptr = num_str;
      break;
    }

    sum = sum * base + char_to_int(*num_str, base);
  
    if ((sign == 1) && sum >= INT_MAX)
      return INT_MAX;
    else if (sign == -1 && sum >= -INT_MIN)

    {

      return INT_MIN;
    }
  }

  return (int)sum;
}

int strtol(char *num_str, char **endptr, int base)
{

  if (base == 0)
  {
    base = find_base(num_str[0] == '-' ? (num_str + 1): num_str);
  }

  return str_to_int(num_str, endptr, base);
}

int main()
{
  char *endptr = NULL;
  char *num_str = "-A0W000000";
  int base = 16;

  int ans = strtol(num_str, &endptr, base);

  return 0;
}

2,从1亿个数中,找出最大的1000个数。效率要尽可能的高,使用的额外空间要尽可能小。
void max_num(int* source_num,int* max_num)
source_num:数组包括所有的1亿个数。
max_num:保存最大的1000个数。

#注:不能使用任何库函数。

思路:维护一个有1000个元素的最小堆即可。

   比较下一个元素与堆中的最小值,大于则heap_pop(), 再heap_push()。

      最后堆中的1000个元素即为答案。

程序:

#include <stdio.h>

 

const int MAX_NUM = 5;
const int MAX_SRC = 10;

 

void swap(int &x, int &y)
{
  int temp = x;
  x = y;
  y = temp;
}

void heap_fix_down(int root, int *max_num, int size)
{
  int min_index = root;
  int left = (root << 1) + 1;
  int right = left + 1;

  

  if (left < size && max_num[min_index] > max_num[left])
    min_index = left;

  else if (right < size && max_num[min_index] > max_num[right]­­­)
    min_index = r[right]

  if (min_index != root)
  {
    swap(max_num[min_index], max_num[root]);

    heap_fix_down(min_index, max_num, size);
  }
}

void heap_fix_up(int *max_num, int size)
{
  size = size - 1;
  while (size > 0)
  {
    int p = (size - 1) >> 1; 
    if (max_num[size] < max_num[p])
    {
      swap(max_num[size], max_num[p]);
      size = p;
    }
    else 
      break;
  }
}

void heap_pop(int *max_num, int& size)
{
  max_num[0] = max_num[--size];

  heap_fix_down(0, max_num, size);
}

void heap_push(int val, int *max_num, int& size)
{
  max_num[size++] = val;

  heap_fix_up(max_num, size);
}

void max_1000num(int *source_num, int *max_num)
{
  int i, size = 0;
  for (i = 0; i < MAX_NUM; ++i)
  {
    heap_push(source_num[i], max_num, size);
  }
 
  for (i = MAX_NUM; i < MAX_SRC; ++i)
  {
    if (max_num[0] < source_num[i])
    {

      heap_pop(max_num, size);
      heap_push(source_num[i], max_num, size);
    }
  }

}

int main()
{
  int source_num[MAX_SRC] = {100, 50, 10, 11, 3, 9, 13, 55, 77, 99};
  int max_num[MAX_NUM];

  max_1000num(source_num, max_num);

  return 0;
}

3,若对于整数N,在集合{1,2……,N}中找出m个数,使其和等于剩下的N-m个数的和。返回所有可能的组合数。N<10000。

#注:不能使用任何库函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值