日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【结论】【dfs】费解的开关(joyoi-tyvj 1266)

發(fā)布時間:2023/12/3 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【结论】【dfs】费解的开关(joyoi-tyvj 1266) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

費解的開關(guān)

joyoi-tyvj 1266

題目大意:

有5*5的一個圖,每個點的數(shù)值是1或0,如果將一個點的數(shù)值取反,那這個點上下左右的點都會取反,現(xiàn)在問你將所有點都變?yōu)?最少要多少步,如果步數(shù)大于6或無法全變成1的話就輸出-1(有n組數(shù)據(jù))

輸入樣例

3 00111 01011 10001 11010 1110011101 11101 11110 11111 1111101111 11111 11111 11111 11111

輸出樣例

3 2 -1

解題思路:

首先我們可以發(fā)現(xiàn)一個點取反兩次和沒取反是一樣的,所以我們可以暴力枚舉25個點變不變,但這樣就要o(22525n)o(2^{25}25n)o(22525n),就絕對會炸
然后我們一行一行地來看,可以發(fā)現(xiàn)如果當(dāng)前行處理后,當(dāng)前行0的位置下方必須點,1的位置下方不能點,然后我們就可以只枚舉第一行然后剩下的直接算出來,最后直接判斷最后一行合不合法即可,時間復(fù)雜度o(2525n)o(2^{5}25n)o(2525n)

代碼:

#include<cstdio> #define min(a,b) (a)<(b)?(a):(b) using namespace std; int n,ans,a[7][7],b[7][7]; int js() {int sum=0;for (int i=1;i<=5;++i)for (int j=1;j<=5;++j)b[i][j]=a[i][j];//用b來臨時計算for (int i=1;i<=4;++i)for (int j=1;j<=5;++j)if (!b[i][j])//如果是0就下方的數(shù)取反{b[i][j]^=1;b[i+1][j]^=1;b[i+2][j]^=1;b[i+1][j-1]^=1;b[i+1][j+1]^=1;sum++;}for (int i=1;i<=5;++i)if (!b[5][i])//不合法return 10;//超過6就可以了return sum; } void dfs(int dep,int x) {if (dep>5){ans=min(ans,x+js());//求最小值return;}a[1][dep]^=1;//取反a[1][dep-1]^=1;a[1][dep+1]^=1;a[2][dep]^=1;dfs(dep+1,x+1);a[1][dep]^=1;//不取反a[1][dep-1]^=1;a[1][dep+1]^=1;a[2][dep]^=1;dfs(dep+1,x);return; } int main() {scanf("%d",&n);for (int t=1;t<=n;++t){for (int i=1;i<=5;++i)for (int j=1;j<=5;++j)scanf("%1d",&a[i][j]);//輸入一位數(shù)ans=10;dfs(1,0);printf("%d\n",ans<7?ans:(-1));}return 0; }

總結(jié)

以上是生活随笔為你收集整理的【结论】【dfs】费解的开关(joyoi-tyvj 1266)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。