没有特殊配置,如果有DHCP就配置
DEVICE="eth0"BOOTPROTO="dhcp"
BOOTPROTOv6="dhcp"
ONBOOT="yes"
没有就配置成:
DEVICE="eth0"BOOTPROTO="static"
ONBOOT="yes"
IPADDR=“IP地址”
IPV6ADDR=“IP地址/前缀”
NETMASK="子网掩码"
GATEWAY=“网关地址”
想象空中有两个水杯,水杯的口对着另一个水杯的口。【】 用左边的这个中括号组成的图形形容下吧,左括号是个水杯,即栈,右括号也是个水杯,也是栈。如果你想要提取队列中间的元素,是不是可以把队列中间这个元素到队首之间的所有元素压入左栈中,而把队列中间这个元素到队尾之间的所有元素压入右栈中,提取了这个元素后,再把右栈中元素压到左栈恢复成和原先顺序不变的队列呢,想想是不是很方便。~\(≧▽≦)/~其实这个也linux shell中,通过上下按键便能调出最近的命令使用记录一样的原理
单栈排序Tom最近在研究一个有趣的排序问题:有一个1~n的输入序列和1个栈S,Tom希望借助以下2种 *** 作实现将输入序列升序排序。
*** 作a:如果输入序列不为空,将第一个元素压入栈S1
*** 作b:如果栈S1不为空,将S1栈顶元素d出至输出序列
如果一个1-n的排列P可以通过一系列 *** 作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可单栈排序排列”。
【输入】第一行是一个整数n。第二行有n个用空格隔开的正整数,构成一个1~n的排列。
【输出】输出文件共一行,如果输入的排列不是“可单栈排序排列”,输出数字0;否则输出字典序最小的 *** 作序列,每两个 *** 作之间用空格隔开,行尾没有空格。
------------------------------
定理:考虑对于任意两个数q[i]和q[j],它们不能压入同一个栈中的充要条件: 存在一个k,使得i<j<k且q[k]<q[i]<q[j]。
充分性证明:即如果满足上述条件,那么q[i]和q[j]一定不能压入同一个栈:
反证法:假设这两个数压入了同一个栈,那么在压入q[k]的时候栈内情况如下:
+----+
|q[j] |
+----+
|...|
+----+
|q[i] |
+----+
因为q[k]比q[i]和q[j]都小,所以很显然,当q[k]没有被d出的时候,另两个数也都不能被d出(否则输出序列的数字顺序就不是1,2,3,…,n了)。而之后,无论其它的数字在什么时候被d出,q[j]总是会在q[i]之前d出,而q[j]>q[i],这显然是不正确的.
必要性证明:如果两个数不可以压入同一个栈,那么它们一定满足上述条件。
证明逆否命题:也就是"如果不满足上述条件,那么这两个数一定可以压入同一个栈." 不满足上述条件有两种情况:
情况1:对于任意i<j<k且q[i]<q[j],q[k]>q[i]
情况2:对于任意i<j,q[i]>q[j].
第一种情况:在q[k]被压入栈的时候,q[i]已经被d出栈。那么,q[k]不会对q[j]产生任何影响(这里可能有点乱,因为看起来,q[j]<q[k]的时候是会有影响的,但实际上,这还需要另一个数r,满足j<k<r且 q[r]<q[j]<q[k],也就是证明充分性的时候所说的情况…而事实上我们现在并不考虑这个r,所以说q[k]对q[j]没有影响)。 第二种情况:可以发现这其实就是一个降序序列,所以所有数字都可以压入同一个栈.这样,原命题的逆否命题得证,所以原命题得证。
由此得出有解的判断方法:对所有的数对(i,j)满足1≤i<j≤n,检查是否存在i<j<k满足q[k]<q[i]。
var
n,top,i,j,k:longint{序列长度为n,栈指针为top}
ans:string{ *** 作序列}
st:array [1..1000000] of longint{栈}
begin
read(n){读序列长度}
top:=0j:=1ans:=''{栈和输出序列空,从1开始输出}
for i:=1 to n do{依次处理每个数字}
begin
read(k)ans:=ans+'a 'inc(top)st[top]:=k{读当前数字,进行a *** 作,该数字入栈}
while st[top]=j do {若栈顶满足递增要求,则出栈(进行b *** 作),下一个输出数字应+1,这一过程反复进行,直至不满足条件为止}
begin dec(top)inc(j)ans:=ans+'b 'end end
if j<=n {若未输出1¨n,则失败退出;否则输出 *** 作序列}
then writeln(0)
else writeln(copy(ans,1,length(ans)-1))
end.
================================================================
双栈排序
【问题描述】Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种 *** 作实现将输入序列升序排序。
*** 作a:如果输入序列不为空,将第一个元素压入栈S1
*** 作b:如果栈S1不为空,将S1栈顶元素d出至输出序列
*** 作c:如果输入序列不为空,将第一个元素压入栈S2
*** 作d:如果栈S2不为空,将S2栈顶元素d出至输出序列
+--------------------
s1 |
+--------------------
+--------------------
s2 |
+--------------------
如果一个1~n的排列P可以通过一系列 *** 作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。
例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的 *** 作序列:<a,c,c,b,a,d,d,b>
(这个图网上有,你自己找找吧)
当然,这样的 *** 作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的 *** 作序列。Tom希望知道其中字典序最小的 *** 作序列是什么。
【输入】输入文件twostack.in的第一行是一个整数n。第二行有n个用空格隔开的正整数,构成一个1~n的排列。
【输出】输出文件twostack.out共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的 *** 作序列,每两个 *** 作之间用空格隔开,行尾没有空格。
========================================
简述题意
有两个队列和两个栈,分别命名为队列1(q1),队列2(q2),栈1(s1)和栈2(s2)。最初的时候,q2,s1和s2都为空,而q1中有n个数(n≤1000),为1~n的某个排列.现在支持如下四种 *** 作: a *** 作,将 q1的首元素提取出并加入s1的栈顶; b *** 作,将s1的栈顶元素d出并加入q2的队列尾;
c *** 作,将 q1的首元素提取出并加入s2的栈顶; d *** 作,将s2的栈顶元素d出并加入q2的队列尾;请判断,是否可以经过一系列 *** 作之后,使得q2中依次存储着1,2,3,…,n.如果可以,求出字典序最小的一个 *** 作序列.
1、判断是否有解和任意两个数能否压入同一个栈
⑴、对任意两个数q[i]和q[j],若存在一个k,使得i<j<k且q[k]<q[i]<q[j],则这两个数分别入s1栈和s2栈
⑵、将s1栈和s2栈中的数字组合成两个顶点子集,同一顶点子集内不会出现任何连边,即不能压入同一个栈的所有数字被分到了两个栈中。任两个不在同一栈的数字间连边。此时我们只考虑检查是否有解,所以只要化O(n)时间检查这个图是不是二分图,就可以得知是否有解了。
======================================================
二分图及二分图的匹配
二分图是一种特殊类型的图:图中的顶点集被划分成X与Y两个子集,图中每条边的两个端点一定是一个属于X而另一个属于Y。二分图的匹配是求边的一个子集,该子集中的任意两条边都没有公共的端点。
======================================================
找字典序最小的解
1、确定每个数字入哪个栈,即构造二分图
把二分图染成1和2两种颜色,染色为1的结点被压入s1栈, 染色为2结点被压入s2栈。为了字典序尽量小,我们希望让编号小的结点优先压入s1栈。由于二分图的不同连通分量之间的染色是互不影响的,所以可以每次选取一个未染色的编号最小的结点,将它染色为1,并从它开始DFS染色,直到所有结点都被染色为止。这样,我们就得到了每个结点应该压入哪个栈中。
2、从数字1开始,按照目标序列的递增顺序构造 *** 作序列
先处理入栈:按照搜索递增顺序每个顶点:若顶点i的颜色为1,则进行a *** 作,q1[i]入s1栈;若顶点i的颜色为2,则进行c *** 作,q1[i]入s2栈。
后处理出栈:若s1栈的栈顶元素为目标序列的当前数字k,则进行b *** 作,数字k出s1栈;若s2栈的栈顶元素为目标序列的当前数字k,则进行d *** 作,数字k出s2栈。
然后k+1,继续模拟,直至k为n为止。
==========================================================
数据结构
var
a,b,head,next,point,color:array[0..2001]of longint{初始序列为a(对应q1),后缀的最小值序列为b,其中b[i]=min{a[k]}(i<=k<=n);邻接表的表首顶点为head,后继指针为next,顶点序列为point,顶点的涂色序列为color}
s:array[1..2,0..1000]of longint{s[1]栈,栈首指针为s[1,0]s[2]栈, 栈首指针为s[2,0]}
n,p,i,j,last:longint{序列长度为n,当前应取数字为last}
procedure badend{输出失败信息}
begin
writeln(0)close(output)halt
end
procedure addedge(a,b:longint){(a,b)进入邻接表}
var t:longint
begin
inc(p)point[p]:=b{增加顶点b}
if head[a]=0 {(a,b)进入邻接表}
then head[a]:=p
else begin
t:=head[a]
while next[t]<>0 do t:=next[t]
next[t]:=p
end
end
procedure dfs(now:longint)
var t:longint
begin
t:=head[now]{搜索与顶点now相邻的所有顶点}
while t<>0 do
begin
if color[point[t]]=0{若顶点now相邻的顶点point[t]未涂色,则该顶点涂互补色,沿该顶点递归下去}
then begin
color[point[t]]:=3-color[now]dfs(point[t])
end
if color[point[t]]=color[now] then badend{若顶点now与相邻顶点point[t]涂相同色,则失败退出}
t:=next[t]{访问与顶点now相邻的下一个顶点}
end
end
begin
assign(input,'twostack.in')reset(input){输入文件读准备}
assign(output,'twostack.out')rewrite(output){输出文件写准备}
fillchar(s,sizeof(s),0)fillchar(a,sizeof(a),0){两栈空}
readln(n){读入排列}
for i:=1 to n do read(a[i])
b[n+1]:=maxlongintp:=0
for i:=n downto 1 do{计算b[i]=}
begin
b[i]:=b[i+1]
if a[i]<b[i] then b[i]:=a[i]
end
for i:=1 to n do
for j:=i+1 to n do
if (b[j+1]<a[i])and(a[i]<a[j]) {若a[i]和a[j]不能不能压入同一个栈,则(i,j)和(j,i)进入邻接表}
then begin addedge(i,j)addedge(j,i)end
for i:=1 to n do{所有未涂色的顶点涂颜色1,递归}
if color[i]=0 then begin color[i]:=1dfs(i)end
last:=1{目标序列初始化}
for i:=1 to n do{模拟输出序列}
begin
if color[i]=1 {a[i]入s[1]或s[2]栈}
then write('a ')
else write('c ')
inc(s[color[i],0])s[color[i],s[color[i],0]]:=a[i]
while (s[1,s[1,0]]=last)or(s[2,s[2,0]]=last) do
begin{将s[1]或s[2]栈顶的数字last取出}
if s[1,s[1,0]]=last then begin write('b ')dec(s[1,0])end{将s[1]栈顶的last取出}
if s[2,s[2,0]]=last then begin write('d ')dec(s[2,0])end{将s[2]栈顶的last取出}
inc(last){按递增要求取下一个数字}
end
end
close(input)close(output){关闭输入输出文件}
end.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)