开关灯(jzoj 3926)
生活随笔
收集整理的這篇文章主要介紹了
开关灯(jzoj 3926)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
開關燈
jzoj 3926
題目大意
有一個n×l的燈網,你可以把按某一列的燈的按鈕,然后這一列開的關,關的開,你也可以把某一行的燈和別的行的燈調換,問從當前狀態到目標狀態最少按多少個按鈕
輸入樣例
3 3 2 01 11 10 11 00 10 2 3 101 111 010 001 2 2 01 10 10 01輸出樣例
1 Impossible 0樣例解釋
第一組測試數據,按第2列開關,得到00, 10, 11,然后依次交換后兩行和前兩行即可。
第二組測試數據,可以證明不可能達到要求的方案。
第三組測試數據,只需交換兩行即可。
數據范圍
40% 的數據:1?N,L?10.1 \leqslant N, L \leqslant 10.1?N,L?10.
100% 的數據:1?N?150,1?L?50,1?T?4.1 \leqslant N \leqslant 150,1 \leqslant L \leqslant 50,1 \leqslant T \leqslant 4.1?N?150,1?L?50,1?T?4.
解題思路
我們枚舉當前狀態的第一行和目標狀態的第幾行配對,然后我們可以用異或求出某一行是否按,然后我們看看剩下的行是否能找到可配對的行,如果都有
那這就是一組解,然后求最小值即可
代碼
#include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; ll t, n, l, ans, g, pp, p[200], a[200], b[200]; string str; ll js(ll x)//看有多少個1 {ll sum = 0;while(x) sum += x&1, x>>=1;return sum; } int main() {scanf("%lld", &t);while(t--){memset(a, 0, sizeof(a));memset(b, 0, sizeof(b));scanf("%lld %lld", &n, &l);for (ll i = 1; i <= n; ++i){cin>>str;for (ll j = 1, g = 1; j <= l; ++j, g <<= 1)a[i] += (str[j - 1] - 48) * g;//轉換為數字}for (ll i = 1; i <= n; ++i){cin>>str;for (ll j = 1, g = 1; j <= l; ++j, g <<= 1)b[i] += (str[j - 1] - 48) * g;}ans = 51;for (ll i = 1; i <= n; ++i){memset(p, 0, sizeof(p));g = a[1]^b[i];//那些要按p[i] = 1;//是否用過pp = 1;//是否找到配對的for (ll j = 2; j <= n; ++j){pp = 0;for (ll k = 1; k <= n && !pp; ++k)if (!p[k] && (a[j]^b[k]) == g)//未用過且可以配對p[k] = 1, pp = 1;if (!pp) break;}if (pp) ans = min(js(g), ans);//求最小值}if (ans == 51) printf("Impossible\n");else printf("%lld\n", ans);}return 0; }總結
以上是生活随笔為你收集整理的开关灯(jzoj 3926)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 近似乘积(jzoj 3925)
- 下一篇: 纪中B组模拟赛总结(2020.2.09)