给定一个如下的二维数组a[][]
1 3 5 7 4
2 1 8 6 5
4 0 -1 -2 6
求其中的最长递减子序列:7, 5, 3, 1, 0, -1, -2,长度为7。子序列只能朝向上下左右四个方向,不能朝对角线方向。
思路:
该题一看感觉可以用动态规划做,但是下标不确定从哪里开始算起,因为有上下左右四个方向,没有办法顺序计算。只有用递归的方法来做。用一个函数FindMax(i, j)来表示以该位置起始的最长递减子序列的长度,那么只要取FindMax(i-1, j)、FindMax(i+1, j)、FindMax(i, j-1)、FindMax(i, j+1)中的最大值,然后加1即可,当然前提是上下左右的元素比(i, j)的元素小。
代码如下:
#include <iostream>
#include <assert.h>
using namespace std;
int Max(int a, int b, int c, int d)
{
a = (a > b) ? a : b;
a = (a > c) ? a : c;
return (a > d) ? a : d;
}
int FindMax(int a[], int res[], bool flag[], int m, int n, int i, int j)
{
int umax = 0, dmax = 0, lmax = 0, rmax = 0;
//当前元素的下标
int cur = i * n + j;
//上面的元素
int up = (i - 1) * n + j;
//如果存在上面的元素,并且当前元素大于上面元素,就计算上面元素的最长路径
if (i > 0 && a[cur] > a[up])
{
//如果上面元素的标记为false,说明上面元素的最长路径还没有计算
if (!flag[up])
{
//计算上面元素的最长路径,计算结束后将上面元素的标记赋值为true
umax = FindMax(a, res, flag, m, n, i-1, j);
res[up] = umax;
flag[up] = true;
}
//如果上面元素的标记为true,说明已经计算过,直接取结果
else
umax = res[up];
}
//下面的元素
int down = (i + 1) * n + j;
if (i < m-1 && a[cur] > a[down])
{
if (!flag[down])
{
dmax = FindMax(a, res, flag, m, n, i+1, j);
res[down] = dmax;
flag[down] = true;
}
else
dmax = res[down];
}
//左边的元素
int left = i * n + j - 1;
if (j > 0 && a[cur] > a[left])
{
if (!flag[left])
{
lmax = FindMax(a, res, flag, m, n, i, j-1);
res[left] = lmax;
flag[left] = true;
}
else
lmax = res[left];
}
//右边的元素
int right = i * n + j + 1;
if (j < n-1 && a[cur] > a[right])
{
if (!flag[right])
{
rmax = FindMax(a, res, flag, m, n, i, j+1);
res[right] = rmax;
flag[right] = true;
}
else
rmax = res[right];
}
//当上下左右元素的值都计算完,就可以计算当前元素的最长路径了
flag[cur] = true;
res[cur] = 1 + Max(umax, dmax, lmax, rmax);
return res[cur];
}
int LDS(int a[], int m, int n)
{
assert(a != NULL && m > 0 && n > 0);
int* res = new int[m * n];
memset(res, 0, m*n*sizeof(int));
bool* flag = new bool[m * n];
memset(flag, false, m*n*sizeof(bool));
int max = 0;
//计算以每个元素起始的最长路径长度,并记录全局的最长路径长度max
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
int cur = i * n + j;
if (!flag[cur])
FindMax(a, res, flag, m, n, i, j);
if (max < res[cur])
max = res[cur];
}
}
delete [] res;
delete [] flag;
return max;
}
void main()
{
int a[] = {
100,100,18,19,20,
10,100,16,100,14,
12,14,15,100,12,
100,100,11,100,11,
100,100,9,100,7};
int m = 5, n = 5;
cout << LDS(a, m, n) << endl;
}
1.简介
WIZ812MJ是一款内嵌了W5100(TCP/IP硬件芯片,内置PHY)、MAG-JACK(带变压器的RJ45)和其他胶连逻辑的网络模块。它可以当作一个组件使用,而且不需要为W5100和变压器准备接口。对于那些想要快速的开发互联网应用系统的用户来说,WIZ812MJ是一个理想的选择。
想了解更多关于硬件TCP/IP应用的信息,请参阅W5100的数据手册。WIZ812MJ 由 W5100 和 MAG-JACK 组成。
- TCP/IP, MAC 层协议: W5100
- 物理层: 内置 W5100
- 接口: MAG-JACK(带变压器的RJ45)
- 支持10/100 Base TX
- 支持半/全双工
- 支持自动协商和自动交叉检测
- 符合IEEE 802.3/802.3u标准
- 工作电压3.3V,I/O口可承受5V电压
- 支持网络状态指示器LED
- 内置硬件互联网协议:TCP,IP Ver.4,UDP,ICMP,ARP,PPPoE,IGMP
- 内置硬件以太网协议:DLC,MAC
- 支持同时的4个独立连接
- 支持单片机总线接口和SPI接口
- 支持直接/间接模式总线访问
- 支持接口API以便应用程序开发
- 2.54mm间距2 x10排针接口
- 温度:0 ~ 70℃ (工作), -40 ~ 85℃ (贮存)
1.3. WIZ811MJ和WIZ812MJ之间的区别
2.引脚分配 & 描述 2.1. 引脚分配
这是一个非常简单的攻击。
两个页面如下:
<form action="MyJsp.jsp" method="get">
<input type="text" name="content"/>
<input type="submit" values="submit"/>
</form><%
out.print(request.getParameter("content"));
%>如果攻击者在输入框里面输入以下内容:<script>alert('Help me ask you sisiter hello...')</script>那么就有以下结果:
当然,用户还可以输入:
<script>alert(document.cookie)</script>
用户还可以直接在地址栏输入:如下:
不仅可以注入script,还可以直接注入html代码。。。
http://localhost:8080/Test/MyJsp.jsp?content=<script><a href=/blog_article/"http_/weibo.com/shangaoquangengqing">My/index.html Weibo</a></script>
攻击者输入的内容可以改的,大家都明白这是很危险的。
这个在高级的浏览器,比如现在的360急速浏览器是不能通过的,具体原因未深究。
防范方法很多,最简单的就是将代码的一下基本字符替换掉,比如< > " \等。
以后写代码留意一点就行。