description
給定1到n的乙個排列,再給定一些允許的交換方法,要求用最少的交換次數把該排列變為1,2,3,,,n。
input
第一行包含兩個整數n(1<=n<=12)和m(1<=m<=n*(n-1)/2),表示序列的長度以及允許的交換方案。
第二行輸入1到n個初始排列情況。
接下來m行,每行兩個整數a和b描述乙個允許的交換方案,表示允許把當前排列中的第a個數和第b個數進行交換,保證a和b不相同。
輸入保證一定存在解。
output
輸出乙個整數表示最少需要的交換次數。
sample input
輸入1:
2 12 1
1 2輸入2:
3 22 1 3
1 32 3
輸入3:
5 51 2 3 4 5
1 52 5
1 41 1
3 5sample output
輸出1:
輸出2:
輸出3:
觀察資料範圍,發現這裡的n很小,也許可以用暴力來處理。
但是,如果用暴力的話,會出現很多重複狀態,而且效率不高。
開始的起始狀態我們是知道的,最終轉移到的狀態我們也是知道的,而且每種操作的改變對於正著做和反著做都是相同的。
不過,我們如何記錄它的狀態?
開應該12維的布林陣列是不太科學的,
因為n很小只用12,而且
1213
=106993205379072
這個數是可以用long long存的下的。
那麼我們就將每乙個序列看成應該12進製的數,再將它轉換成為應該10進製數。
這樣,我們就可以將每乙個序列變成乙個數。
然而,這裡可能出現的狀態不是很多,我們可以用hash表來儲存和判重。
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define mo 1000007
using
namespace
std;
ll ha[mo];
bool bz[mo];
int g[mo];
ll data[3*mo],da1[3*mo],z[15],s;
int a[15],t[15],f[15],cz[150][2];
int n,m,l,now;
int hash(ll x)
ll zz()
void aa(ll x)
}int main()
for(int i=1;i<=m;i++)
scanf("%d%d",&cz[i][0],&cz[i][1]);
da1[1]=zz();
l=hash(da1[1]);
ha[l]=da1[1];
bz[l]=1;
memcpy(t,a,sizeof(t));
data[1]=zz();
l=hash(data[1]);
ha[l]=data[1];
if(da1[1]==data[1])
int i=0,j=1,p=0,q=1;
while((ifor(int k=1;k<=m;k++)
}else
}p++;
aa(da1[p]);
now=g[hash(da1[p])];
for(int k=1;k<=m;k++)
}else }}
}
14 4 選單功能
選單功能就是與使用者的溝通介面。1 在workermanager.h標頭檔案中新增show menu 成員函式。class workermanager 2 在workermanager.cpp中實現show menu 成員函式。其實這個函式就是在螢幕中把選單介面列印出來,沒什麼技術含量。顯示選單 v...
14 4 執行緒的通訊
執行緒通訊 乙個執行緒完成自己的任務時,就要通知另外乙個執行緒去 例子就是生產者與消費者關係 wait 等待。如果執行緒執行了wait方法,那麼該執行緒會進入等待的狀態 notify 喚醒等待的執行緒 注意 1 wait和notify方法是屬於objeck類的。2 wait和notify方法必須是要...
南陽144 某種序列
時間限制 3000 ms 記憶體限制 65535 kb 難度 4 描述 數列a滿足an an 1 an 2 an 3,n 3 編寫程式,給定a0,a1 和 a2,計算a99 輸入 輸入包含多行資料 每行資料報含3個整數a0,a1,a2 0 a0,a1,a2 100000000 資料以eof結束 輸出...