本文正體字版由OpenCC轉換
昨天晚上做了清北學堂的比賽“首屆信息學在線測評大賽Q1”,名字很響亮。今天寫了一份題解,發出來。
第一題:低價購買
要求求出方案數的最長單調序列(LIS)問題。我把序列先倒轉了過來,然後求最長上升序列。由於需要去除重複序列,可以增加一個域Next[i],定義Next[i]=min{ k | k>i 且 A[k]=A[i] },表示大於i且離i最近的Next[i],使得第Next[i]個數與第i個數相同。如果不存在這樣的數則Next[i]=無窮大。這樣的話如果出現Next[i]不爲0且Next[j]<i可直接跳過。
狀態設定 F[i]爲以第i個元素爲結尾的最長上升序列的長度 G[i]爲以第i個元素爲結尾的最長上升序列的方案數
狀態轉移方程
F[i] = Max{ F[j] + 1 | A[j] < A[i] 且 Next[j] > i } G[i] = Sum{ G[j] | F[j] + 1 = F[i] }
邊界條件
G[0]=1
爲了方便,增加一個極大的元素到序列結尾。這樣目標狀態爲 最長長度 F[N+1]-1 方案數 G[N+1]
第二題:連續串之和
相鄰元素絕對值之差必須爲1,所以顯然構造出的和最大的序列一定爲0,1,2,3,…,N-1,和爲(N-1)*N/2,最小和同理爲-(N-1)*N/2。於是如果給定的S不在最大值與最小值的區間內,一定無解。
我們先生成一個和最大的序列,0,1,2,3,…,N-1,然後再考慮調整使得滿足條件。假設當前的和與S的差爲D,可以發現,無論怎樣變換序列,D的奇偶性的不改變的。因爲無論改變那個元素,都只能從比前一個元素多1變成少1,或者從比前一個元素少1變成多1,調整多個也是一樣的,變化量爲偶數。所以說,如果初始的D爲奇數,則一定不可能有解。
餘下來的情況一定爲有解的情況了。把序列順序做差,初始化每項差值都爲1,則對應了0,1,2,3,…,N-1。可以發現,修改一個差值從1到-1會引起後面所有項的值減少2,總的減少量就是後面項的個數*2。這時就可以設計出算法了,從第一個差值開始嘗試從1變成-1,更新當前和,直到等於S爲止。最後再根據差值序列還原出原序列。時間複雜度爲O(N)。
第三題:決鬥
觀察發現,如果第i個人想與第j個人決鬥(i<j),i,j必須相鄰,也就是i,j之間的人必須全部被打敗。換句話說,如果i,j相鄰,一定存在一個k(i<k<j),使得i,k相鄰,k與j相鄰,而且i可以打敗k或者j可以打敗k。這樣就把問題縮小了,可以以此進行動態規劃。考慮到是一個環,我們可以把N個人複製一遍,接在後面。
設定狀態 F[i,j] 表示第i個人是否可以與第j個人相鄰 (1<=i<j<=N*2),第i個人在環上另一面的映射爲i+N
狀態轉移方程 F[i,j]= Or { F[i,k]=F[k,j]=true | i可以打敗k或j可以打敗k }
邊界條件 由於i和i+1兩個一定是相鄰的,所以有 F[i,i+1]=true
判斷第i個人可以勝出的條件就是F[i,i+N]=true,此時i兩邊的人全部敗了,i獲勝。
時間複雜度O(N^3)。
第四題:最小費用多米諾
把棋盤上每個非障礙格子看作一個頂點,相鄰兩個非障礙格子對應的頂點連接一條邊,權值爲在這兩個格子上放上多米諾方塊的費用。判斷是否能放滿只需求出該圖的最大匹配,並判斷是否每個頂點都有匹配。如何求最大匹配?帶花樹?不,這是一個二分圖!
爲什麼是二分圖?因爲棋盤是可以2染色的,之間有邊的頂點都是相鄰的,而相鄰的格子必然是顏色不同的,所以這是一個二分圖。
接下來就容易了,首先求出最大匹配,如果存在完美匹配(每個頂點都有匹配),再求最佳匹配(最小權值完備匹配)即可。
下面是四個題的程序
第一題:低價購買
/*
* Problem: RQN Q1 低價購買
* Author: Guo Jiabao
* Time: 2009.5.2 21:48
* State: Solved
* Memo: 動態規劃 LIS
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXN=50001,INF=0x7FFFFFFF;
using namespace std;
int F[MAXN],G[MAXN],A[MAXN],Next[MAXN];
int N,Ans=-INF,Ans2;
void init()
{
int i,j;
freopen("low.in","r",stdin);
freopen("low.out","w",stdout);
scanf("%d",&N);
for (i=N;i>=1;i--)
scanf("%d",&A[i]);
Next[0]=INF;
for (i=1;i<=N;i++)
{
Next[i]=INF;
for (j=i+1;j<=N;j++)
if (A[j]==A[i])
{
Next[i]=j;
break;
}
}
A[++N]=INF;
}
void dynamic()
{
int i,j;
memset(G,0,sizeof(G));
G[0]=1;
for (i=1;i<=N;i++)
{
F[i]=0;
for (j=0;j<=i-1;j++)
{
if (Next[j]>i && A[j] < A[i])
{
if (F[j] > F[i])
{
F[i] = F[j];
G[i] = G[j];
}
else if (F[j] == F[i])
G[i] += G[j];
}
}
F[i]++;
}
Ans=F[N]-1;
Ans2=G[N];
}
int main()
{
init();
dynamic();
printf("%d %d",Ans,Ans2);
return 0;
}
第二題:連續串之和
/*
* Problem: RQN Q1 連續串之和
* Author: Guo Jiabao
* Time: 2009.5.1 20:01
* State: Done
* Memo: 構造
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXN=10001;
using namespace std;
int A[MAXN],N,S;
void init()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
scanf("%d%d",&N,&S);
}
void construct()
{
int i,Lim,Dif,k,d;
Lim=N*(N-1)/2;
Dif=Lim-S;
if (S>Lim || S<-Lim || Dif%2==1)
{
printf("NIE");
return;
}
for (i=2;i<=N;i++)
A[i]=1;
for (i=2;i<=N && Dif;i++)
{
k=(N-i+1)*2;
if (Dif >= k)
{
A[i] = -1;
Dif -= k;
}
}
k=0;d=0;
for (i=1;i<N;i++)
{
k += A[i];
d+=k;
printf("%dn",k);
}
k += A[i];
d+=k;
printf("%d",k);
}
int main()
{
init();
construct();
return 0;
}
第三題:決鬥
/*
* Problem: RQN Q1 決鬥
* Author: Guo Jiabao
* Time: 2009.5.1 20:24
* State: Done
* Memo: 動態規劃
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
const int MAXN=1001;
bool F[MAXN][MAXN];
bool Beat[MAXN][MAXN];
int N,N2,Wcnt;
int Win[MAXN];
void init()
{
int i,j,c;
freopen("mus.in","r",stdin);
freopen("mus.out","w",stdout);
scanf("%d",&N);
N2=N*2;
for (i=1;i<=N;i++)
{
for (j=1;j<=N;j++)
{
scanf("%d",&c);
Beat[i][j]=Beat[i][j+N]=Beat[i+N][j]=Beat[i+N][j+N]= c==1;
}
}
}
void dynamic()
{
int i,j,k,l;
for (i=1;i<N2;i++)
{
F[i][i+1]=true;
}
for (l=3;l<=N+1;l++)
{
for (i=1;i<=N2;i++)
{
if ((j=i+l-1)>N2)
break;
for (k=i+1;k<=j-1;k++)
{
if (F[i][k] && F[k][j] && (Beat[i][k] || Beat[j][k]))
{
F[i][j]=true;
break;
}
}
}
}
for (i=1;i<=N;i++)
{
if (F[i][i+N])
{
Wcnt++;
Win[ Wcnt ]=i;
}
}
printf("%dn",Wcnt);
for (i=1;i<Wcnt;i++)
{
printf("%dn",Win[i]);
}
printf("%d",Win[i]);
}
int main()
{
init();
dynamic();
return 0;
}
第四題:最小費用多米諾
/*
* Problem: RQN Q1 最小費用多米諾
* Author: Guo Jiabao
* Time: 2009.5.2 19:40
* State: Solved
* Memo: 棋盤2染色 二分圖匹配 匈牙利 費用流
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXN=41,MAXV=MAXN*MAXN,MAXE=MAXV*8,INF=0x7FFFFFFF;
const int dx[4]={0,1,-1,0},dy[4]={1,0,0,-1};
using namespace std;
struct Queue
{
int Q[MAXV],head,tail,size;
bool inq[MAXV];
Queue(){head=size=0,tail=-1;memset(inq,0,sizeof(inq));}
void ins(int p)
{
size++;
if (++tail>=MAXV)
tail=0;
Q[tail]=p;
inq[p]=true;
}
int pop()
{
int r=Q[head];
size--;
if (++head>=MAXV)
head=0;
inq[r]=false;
return r;
}
}Q;
struct edge
{
edge *next,*op;
int t,c,v;
}ES[MAXE],*V[MAXV],*fe[MAXV];
struct point
{
int vx,vy,id,put;
}P[MAXN][MAXN];
int N,M,S,T,MatchCnt,MaxCostFlow,EC,Number;
int color[MAXV],Match[MAXV],sp[MAXV],fp[MAXV],PX[MAXV],PY[MAXV];
bool vis[MAXV];
void init()
{
int i,j;
freopen("domino.in","r",stdin);
freopen("domino.out","w",stdout);
scanf("%d%d",&N,&M);
for (i=1;i<=N;i++)
for (j=1;j<=M;j++)
{
scanf("%d",&P[i][j].vx);
if (P[i][j].vx)
Number++;
}
for (i=1;i<=N;i++)
for (j=1;j<=M;j++)
scanf("%d",&P[i][j].vy);
}
inline bool inrange(int x,int y)
{
return x>=1 && x<=N && y>=1 && y<=M;
}
void dye(int x,int y,int c)
{
P[x][y].id=++T;
PX[T]=x; PY[T]=y;
color[T]=c;
for (int k=0;k<4;k++)
{
int px=x+dx[k],py=y+dy[k];
if (inrange(px,py) && P[px][py].vx && !P[px][py].id)
{
dye(px,py,3-c);
}
}
}
inline void addedge(int a,int b,int c,int v)
{
ES[++EC].next=V[a];
V[a]=ES+EC; V[a]->t=b; V[a]->c=c; V[a]->v=v;
ES[++EC].next=V[b];
V[b]=ES+EC; V[b]->t=a; V[b]->c=0; V[b]->v=-v;
V[a]->op=V[b]; V[b]->op=V[a];
}
void makegraph()
{
int i,j,k,px,py,a,b,v;
for (i=1;i<=N;i++)
for (j=1;j<=M;j++)
if (P[i][j].vx && !P[i][j].id)
dye(i,j,1);
for (i=1;i<=N;i++)
for (j=1;j<=M;j++)
for (k=0;k<2;k++)
{
px=i+dx[k],py=j+dy[k];
if (inrange(px,py))
{
a=P[i][j].id;
b=P[px][py].id;
if (a==0 || b==0) continue;
if (color[b]==1)
{
v=a; a=b; b=v;
}
if (k==0)
v = P[i][j].vx + P[px][py].vx;
else
v = P[i][j].vy + P[px][py].vy;
addedge(a,b,1,v);
}
}
S=0;T++;
for (i=1;i<T;i++)
{
if (color[i]==1)
addedge(S,i,1,0);
else
addedge(i,T,1,0);
}
}
bool path(int i)
{
for (edge *e=V[i];e;e=e->next)
{
int j=e->t;
if (!vis[j] && e->c>0)
{
vis[j]=true;
if (Match[j]==0 || path(Match[j]))
{
Match[j]=i;
return true;
}
}
}
return false;
}
bool hungary()
{
for (int i=1;i<T;i++)
{
if (color[i]==1 && !Match[i])
{
memset(vis,0,sizeof(vis));
if (path(i))
MatchCnt++;
}
}
return MatchCnt*2==Number;
}
bool spfa()
{
int i,j;
for (i=S;i<=T;i++)
sp[i]=INF;
sp[S]=0;
Q.ins(S);
while (Q.size)
{
i=Q.pop();
for (edge *e=V[i];e;e=e->next)
{
j=e->t;
if (e->c && sp[i] + e->v < sp[j])
{
sp[j] = sp[i] + e->v;
fp[j] = i;
fe[j] = e;
if (!Q.inq[j])
Q.ins(j);
}
}
}
return sp[T]!=INF;
}
void CostFlow()
{
int i,delta;
while (spfa())
{
delta=INF;
for (i=T;fp[i];i=fp[i])
if (fe[i]->c < delta)
delta = fe[i]->c;
for (i=T;fe[i];i=fp[i])
{
fe[i]->c -= delta;
fe[i]->op->c +=delta;
}
MaxCostFlow += delta * sp[T];
}
for (i=1;i<T;i++)
{
if (color[i]==1)
{
for (edge *e=V[i];e;e=e->next)
{
if (e->c==0)
{
Match[e->t] = i;
break;
}
}
}
}
}
void print(int Ans)
{
int i,j;
printf("%dn",Ans);
for (i=1;i<T;i++)
{
if (color[i]==2)
{
j=Match[i];
if (PX[i]==PX[j])
P[ PX[i] ][ PY[i] ].put = P[ PX[j] ][ PY[j] ].put = 1;
else
P[ PX[i] ][ PY[i] ].put = P[ PX[j] ][ PY[j] ].put = 2;
}
}
for (i=1;i<=N;i++)
{
for (j=1;j<M;j++)
printf("%d ",P[i][j].put);
printf("%d",P[i][j].put);
if (i!=N)
printf("n");
}
}
void solve()
{
makegraph();
if (hungary())
{
CostFlow();
print(MaxCostFlow);
}
else
print(MatchCnt);
}
int main()
{
init();
solve();
return 0;
}
低價購買
<table>
<tbody>
<tr>
<td class="Text0" height="28" bgcolor="#84c1ff">描述</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">“ 低價購買”這條建議是在奶牛股票市場取得成功的一半規則。要想被認爲是偉大的投資者,你必須遵循以下的問題建議:“低價購買;再低價購買”。每次你購買一 支股票,你必須用低於你上次購買它的價格購買它。買的次數越多越好!你的目標是在遵循以上建議的前提下,求你最多能購買股票的次數。你將被給出一段時間內 一支股票每天的出售價(2^16範圍內的正整數),你可以選擇在哪些天購買這支股票。每次購買都必須遵循“低價購買;再低價購買”的原則。寫一個程序計算 最大購買次數。
這裏是某支股票的價格清單:
日期 1 2 3 4 5 6 7 8 9 10 11 12
價格 68 69 54 64 68 64 70 67 78 62 98 87
最優秀的投資者可以購買最多4次股票,可行方案中的一種是:
日期 2 5 6 10
價格 69 68 64 62
數據規模
對於100%的數據,1 <= N <= 5000。
</span></td>
</tr>
<tr>
<td class="Text0" height="24" bgcolor="#84c1ff">輸入格式</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">第1行: N,股票發行天數。
第2行: N個數,是每天的股票價格。
</span></td>
</tr>
<tr>
<td class="Text0" bgcolor="#84c1ff">輸出格式</td>
</tr>
<tr class="TextN">
<td class="Text0"><span class="Text4">輸出僅一行包含兩個數:最大購買次數和擁有最大購買次數的方案數(<=2^31)當二種方案“看起來一樣”時(就是說它們構成的價格隊列一樣的時候),這2種方案被認爲是相同的。</span></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸入</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea" readonly="readonly">12 68 69 54 64 68 64 70 67 78 62 98 87 </textarea></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸出</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea2" readonly="readonly">4 2</textarea></td>
</tr>
</tbody></table>
連續串之和
<table>
<tbody>
<tr>
<td class="Text0" height="28" bgcolor="#84c1ff">描述</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">我們定義連續串爲一串整數,它的第一個元素爲0,並且任兩個相鄰元素之差的絕對值爲1。更精確的說,如果[a1, a2, …, an]爲一個連續串,那麼有:
對於任意的1<k<n,|ak - ak+1|=1
a1=0
任務:
寫一個程序:
讀入連續串的長度和連續串中所有元素的和;
找出一個給定長度的連續串,使其所有元素的和與給定的和相等,或者指出這樣的連續串不存在。
數據規模
對於100%的數據,1 <= n <= 10000,|S| <= 50000000。
輸出任意一個可行解即可,本題的Special Judge已經由RenQing編寫完畢.
最新更新[RQ剛剛出完數據...所以來透露一下]:
對於30%的數據 n<=12 s<=30
對於60%的數據 n<=1000 s<=1500
對於100%的數據 n<=10000 s<=50000000
</span></td>
</tr>
<tr>
<td class="Text0" height="24" bgcolor="#84c1ff">輸入格式</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">輸入的第一行有一個整數n,表示連續串中元素的個數。第二行爲一個整數S,表示連續串中所有元素之和。</span></td>
</tr>
<tr>
<td class="Text0" bgcolor="#84c1ff">輸出格式</td>
</tr>
<tr class="TextN">
<td class="Text0"><span class="Text4">如果能夠找到滿足條件的連續串,你應當輸出n個整數(每行一個),表示連續串中的各個元素(第k個元素輸出在第k行)。否則,文件應該只包含一個單詞NIE。</span></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸入</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea" readonly="readonly">8 4 </textarea></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸出</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea2" readonly="readonly">0 1 2 1 0 -1 0 1</textarea></td>
</tr>
</tbody></table>
決鬥
<table>
<tbody>
<tr>
<td class="Text0" height="28" bgcolor="#84c1ff">描述</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">Michel最近迷上了買彩票。現在,某賭場就一輪決鬥的結果開設了賭局。這個賭局同樣被Michel盯上了,他決定購買這個彩票。
當然,身爲有教養有文化的人,Michel買彩票並不是胡亂買的。他在買之前進行了詳盡的市場調查,並拿到了任意兩個選手對決後的勝敗情況。可以假定正式比賽的時候決鬥後果也是一樣的。
同時決鬥的規則是這樣的:
首先,選手們圍成一個圈。每一回合隨機抽出一個選手的號碼,讓他和他右邊的選手決鬥。開始時,1號右邊的是2號,2號右邊的試三號,依此類推。特別的,n號右邊的是1號。戰敗的選手則退出戰場。例如2號戰敗,則1號右邊的就變成了3號。
現在,他找到了你,希望你能告訴他哪些選手可能贏。
數據範圍:
對於30%的數據,n=5
對於100%的數據,1<=n<=500
[感謝:陳啓峯出題,清北學堂提供]
</span></td>
</tr>
<tr>
<td class="Text0" height="24" bgcolor="#84c1ff">輸入格式</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">輸入數據的第一行爲一個整數n,表示有n個選手。
接下來n行,每行n個整數,第I+1行第J列表示第I個選手與第J個選手對決後的勝敗情況,0表示選手I失敗,1表示選手I獲勝。</span></td>
</tr>
<tr>
<td class="Text0" bgcolor="#84c1ff">輸出格式</td>
</tr>
<tr class="TextN">
<td class="Text0"><span class="Text4">輸出數據的第一行爲一個整數k,表示有多少選手可能贏。
接下來k行,每行一個整數,從小到大輸出這些選手的編號。</span></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸入</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea" readonly="readonly">2 0 0 1 0</textarea></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸出</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea2" readonly="readonly">1 2</textarea></td>
</tr>
</tbody></table>
最小費用多米諾
<table>
<tbody>
<tr>
<td class="Text0" height="28" bgcolor="#84c1ff">描述</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">在 N*M 的棋盤上互不覆蓋地放置 1*2 和 2*1 的多米諾方塊,有一些格子上有障礙,這些格子不能放置多米諾方塊。在每個沒有障礙的格子上有兩個費用值,分別表示這個格子上橫放和豎放多米諾方塊所需的費 用。試問存不存在一種放置多米諾的方案,能放滿所有無障礙的格子。若存在,求出完成放置的最小費用;若不存在,求出最多能放置多少個多米諾。
數據規模
保證第一行的答案不超過 2^30。
對於 30% 的數據,N, M <= 5。
對於 80% 的數據,N, M 中至少有一個不超過8。
對於 100% 的數據,N, M <= 40。
備註
本題設有部分分,對於每種情況,如果你的程序只輸出了第一行且答案正確,可以得到該測試點 70% 的分數。但是如果你的程序輸出了放置方案而方案不正確,該測試點得0分。
[感謝題目作者wish]
</span></td>
</tr>
<tr>
<td class="Text0" height="24" bgcolor="#84c1ff">輸入格式</td>
</tr>
<tr class="TextN">
<td class="Text0" height="24"><span class="Text4">第一行兩個正整數 N 和 M,表示棋盤共 N 行 M 列。
後爲兩個 N*M 的矩陣,分別表示棋盤每個格子橫放和豎放多米諾的費用。費用爲正整數,若費用爲0,則格子是障礙格(保證障礙格兩個費用均爲0)。
</span></td>
</tr>
<tr>
<td class="Text0" bgcolor="#84c1ff">輸出格式</td>
</tr>
<tr class="TextN">
<td class="Text0"><span class="Text4">若存在至少一種放置方案,則第一行輸出最小費用,後跟一個 N*M 的矩陣,表示最小費用方案。
若不存在滿足要求的放置方案,則第一行輸出最多能夠放置多少個多米諾,後跟一個 N*M 的矩陣,輸出一種放置方案。
方案可能有很多種,只需輸出任意一種即可。
輸出的方案中,0表示這個格子不放置多米諾,1表示這個格子的多米諾橫放,2 表示這個格子的多米諾豎放。
</span></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸入</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea" readonly="readonly">3 4 3 5 3 2 3 0 0 3 9 8 2 3 2 8 4 4 8 0 0 2 1 4 3 8 </textarea></td>
</tr>
<tr>
<td class="Text0" align="left" valign="top" bgcolor="#84c1ff">樣例輸出</td>
</tr>
<tr>
<td class="Text0" align="left" valign="top"><textarea cols="80" rows="4" name="textarea2" readonly="readonly">42 1 1 1 1 2 0 0 2 2 1 1 2 </textarea></td>
</tr>
</tbody></table>
上次修改時間 2017-05-26