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]