腾讯面试中的问题

1、给出一个a[n]数组,每个元素不相等,求出这样的数,要求时间复杂度O(n)

(1)比它前面的所有数大

(2)比它后面的所有数小

思路:用动态规划方法

用dp1(i)表示从0到i这之间的数的最大值,其状态转移方程为dp1(i) = max{dp1(i - 1), a[i]}

用dp2(i)表示从i到n-1这之间的数的最小值,其状态转移方程为dp2(i) = min{dp2(i + 1), a[i]}

然后从0到n遍历,如果a[i] == dp1(i)并且a[i] == dp2(i)说明 就是满足条件的

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 10000;

int dp1[MAXN], dp2[MAXN];
int n;
int a[MAXN];

bool input()
{
    if (scanf("%d", &n) != 1) return false;
    if (n == 0) return false;
    
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    
    return true;
}

void solve()
{
    dp1[0] = a[0];
    dp2[n - 1] = a[n - 1];
    
    for (int i = 1; i < n; i++) {
        dp1[i] = max(dp1[i - 1], a[i]);
    }
    
    for (int i = n - 2; i >= 0; i--) {
        dp2[i] = min(dp2[i + 1], a[i]);
    }
    
    for (int i = 0; i < n; i++) {
        if (a[i] == dp1[i] && a[i] == dp2[i]) printf("%d\n", a[i]);
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif
    
    while (input()) {
        solve();
    }
   
    return 0;
}

2、判断机器是不是大端字节序

#include <cstdio>

using namespace std;

union byteorder
{
    char ch;
    short s;
}endian;

void solve()
{
    endian.s = 0x0102;
    
    if (endian.ch == 0x02) printf("little-endian\n");
    else printf("big-endian\n");
}

int main()
{    
    solve();
   
    return 0;
}

3、不用任何库函数,将一个正整数转换成二进制数

#include <cstdio>

using namespace std;

const int MAXN = 100;

int n;

bool input()
{
    if (scanf("%d", &n) != 1) return false;
   
    if (n <= 0) return false;
    
    return true;
}

void solve()
{
    char str[MAXN];
    int len = 0;
    
    while (n) {
        str[len++] = '0' + (n % 2);
        n /= 2;
    }
    
    str[len] = '\0';
    
    for (int i = 0; i < len / 2; i++) {
        char ch = str[i];
        str[i] = str[len - 1 - i];
        str[len - 1 - i] = ch;
    }
    
    printf("%s\n", str);
}

int main()
{    
#ifndef ONLINE_JUDGE
    freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif
    
    while (input()) {
        solve();
    }
   
    return 0;
}

4、对于一个128位的密钥,用非递归的算法列举所有可能的密钥

思路:从右向左找到当前第i位等于0 的位置,将第i位变为1,从i+1到128位的清0

#include <cstdio>
#include <cstring>

using namespace std;

const int MAXN = 128;

char str[MAXN + 1];

void solve()
{
    int i, j;
    
    memset(str, '0', sizeof(str));
    str[MAXN] = '\0';
    
    while (1) {
        for (i = MAXN - 1; i >= 0; i--) {
            if (str[i] == '0') break;
        }
        
        if (i < 0) break;
        
        str[i] = '1';
        for (j = i + 1; j < MAXN; j++) str[j] = '0';
        
        printf("%s\n", str);
    }
}

int main()
{     
#ifndef ONLINE_JUDGE
    freopen("d:\\OJ\\uva_out.txt", "w", stdout);
#endif
    
    solve();
    
    return 0;
}


5、将下列函数写成你熟悉的汇编代码

char get(const char *s, int index)

{

      return s[index];

}

在VS2012中反汇编窗口代码如下:

00E83CB0  push        ebp  
00E83CB1  mov         ebp,esp  
00E83CB3  sub         esp,0C0h  
00E83CB9  push        ebx  
00E83CBA  push        esi  
00E83CBB  push        edi  
00E83CBC  lea         edi,[ebp-0C0h]  
00E83CC2  mov         ecx,30h  
00E83CC7  mov         eax,0CCCCCCCCh  
00E83CCC  rep stos    dword ptr es:[edi]  
	return str[index];
00E83CCE  mov         eax,dword ptr [str]  
00E83CD1  add         eax,dword ptr [index]  
00E83CD4  mov         al,byte ptr [eax]  






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值