題目
挺新奇的一題,用二進位制對應位來表示是第幾個燈,同時也用二進位制來表示對燈的操作,將和這個燈相連的那些燈全部置一,其他置零,那麼我們對某個燈進行操作就只需要和這個燈相異或。比如,0號燈和1,3兩個燈相連,二進位制表示出來就是00…0001011,由於和1相異或狀態取反,和0相異或狀態不變,我們如果改變了第0個燈的狀態,那麼1、3也會改變,而把二進位制表示的狀態和00…0001011相異或就可以得到改變0號燈狀態後的狀態。此外,這個題直接搜尋對所有燈的操作與否複雜度會有2^35,會超時,所以採用折半搜尋,先對前面一半的燈進行操作,並用map儲存達到的狀態及其對應的操作次數,然後對後面一半進行操作,更新答案。
值得一提的是,每個燈最多隻需要操作一次,因為對乙個燈操作兩次就會變回原來的狀態,既然要最少那不如不操作。
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define lowbit(x) ((x)&(-x))
const
int maxn =
1000+10
;const
int maxm =
2000+10
;const
int inf_max =
0x3f3f3f
;const
int mod =
1000000007
;const
double eps =
1e-4
;using
namespace std;
typedef
long
long ll;
inline
intread()
while
(ch>=
'0'&& ch<=
'9') x = x*
10+ ch -
'0',ch =
getchar()
;return x*f;
}mapint>f;
ll a[40]
;int
main()
for(
int i =
0;i <(1
<<
(n/2))
;++i)}if
(!f.
count
(s)) f[s]
= cnt;
else f[s]
=min
(f[s]
,cnt)
;//如果這個狀態存在,肯定取操作次數少的
}int ans =50;
for(
int i =
0;i <(1
<<
(n-n/2)
);++i)
}//後半部分的狀態是s,按照題意s的二進位制後n-n/2位全部為1,和目標狀態相異或後就可以得到前n/2個應該有的狀態
//如果這個狀態用前半部分的操作可以得到,那麼我們更新答案;
if(f.
count((
(1ll
<)^s)
) ans =
min(ans,cnt+f[((
1ll<)^s]);
} cout
}
24,折半查詢
include 折半查詢 二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好 其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 否則利用...
6 2 2 折半查詢
折半查詢,又稱二分查詢,它適用於有序的順序表。基本思路是 首先將給定值key與表中中間位置元素的關鍵字比較,若相等,則查詢成功,返回該元素的儲存位置 若不等,則所需查詢的元素只能在中間元素以外的前半部分或後半部分中 例如,在查詢表公升序排列時,若給定值key大於中間元素的關鍵字,則所查詢的元素只可能...
6 13 折半查詢
給乙個嚴格遞增數列,函式int search bin sstable t,keytype k 用來二分地查詢k在數列中的位置。函式介面定義 int search bin sstable t,keytype k 其中t是有序表,k是查詢的值。裁判測試程式樣例 include using namespa...