给定一个如下的二维数组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急速浏览器是不能通过的,具体原因未深究。
防范方法很多,最简单的就是将代码的一下基本字符替换掉,比如< > " \等。
以后写代码留意一点就行。