题意:
输入一个形如:
-+-- ---- ---- -+--4*4图案,+表示close,-表示open,定义一种操作为:改变某个单元格符号(+变-,-变+),同时单元格所在行与所在列的所有单元格符号都会发生改变。
求最少操作次数能使所有单元格内都是‘-’。并输出要操作的单元格。
思路:
正常的做法和POJ 1573类似,dfs枚举即可,见code1。
这里提供一种高效的做法:
通过思考我们可以验证,某一个单元格内符号为‘+’,同时对其所在行与所在列的所有单元格进行操作(其本身只操作一次),原‘+’单元格元素便会变成‘-’,其余单元格符号均不发生改变。
所以我们可以这么做,对每个‘+’所在行列的单元格进行操作(其本身只操作一次),统计每个单元格被操作的次数,输出奇数次操作数的单元格即可。
代码参见code2.
参考:http://poj.org/showmessage?message_id=156561
AC code1(dfs):
/* * @author Novicer * language : C++/C */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> #define INF 2147483647 #define cls(x) memset(x,0,sizeof(x)) #define rise(i,a,b) for(int i = a ; i <= b ; i++) using namespace std; const double eps(1e-8); typedef long long lint; int ref[6][6] = { }; int r[20],c[20]; int flag = 0 ; int step; vector<pair<int,int> > handle; bool all_open(){ for(int i = 1 ; i <= 4 ; i++) for(int j = 1 ; j <= 4 ; j++) if(!ref[i][j]) return false; return true; } void change(int row , int col){ for(int i = 1 ; i <= 4 ; i++){ ref[i][col] = !ref[i][col]; ref[row][i] = !ref[row][i]; } ref[row][col] = !ref[row][col]; } void dfs(int row , int col , int deep){ if(deep == step){ flag = all_open(); return; } if(flag) return; if(row > 4 || col > 4) return; r[deep] = row; c[deep] = col; change(row,col); if(row < 4) dfs(row+1 , col , deep+1); else dfs(1, col+1 , deep+1); change(row,col); if(row < 4) dfs(row+1 , col , deep); else dfs(1,col+1,deep); return; } void input(){ for(int i = 1 ; i <= 4 ; i++) for(int j = 1 ; j <= 4 ; j++){ char tmp; cin >> tmp; ref[i][j] = (tmp == '-')? 1:0; } } void solve(){ for(step = 0 ; step <= 16 ; step++){ dfs(1,1,0); if(flag) break; } cout << step << endl; for(int i = 0 ; i < step ; i++) cout << r[i] << " " << c[i] << endl; } int main(){ // freopen("input.txt","r",stdin); // freopen("output.txt","w+",stdout); input(); solve(); return 0; }
AC code2:
/* * @author Novicer * language : C++/C */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> #define INF 2147483647 #define cls(x) memset(x,0,sizeof(x)) #define rise(i,a,b) for(int i = a ; i <= b ; i++) using namespace std; const double eps(1e-8); typedef long long lint; int ref[6][6] = {}; int r[20],c[20]; void work(int row , int col){ ref[row][col] = !ref[row][col]; for(int i = 1 ; i <= 4 ; i++){ ref[i][col] = !ref[i][col]; ref[row][i] = !ref[row][i]; } } void input(){ for(int i = 1 ; i <= 4 ; i++) for(int j = 1 ; j <= 4 ; j++){ char tmp; cin >> tmp; if(tmp == '+'){ work(i,j); } } } void solve(){ int ans = 0; for(int i = 1 ; i <= 4 ; i++) for(int j = 1 ; j <= 4 ; j++) if(ref[i][j]){ r[ans] = i; c[ans] = j; ans++; } cout << ans << endl; for(int i = 0 ; i < ans ; i++) printf("%d %d\n",r[i],c[i]); } int main(){ // freopen("input.txt","r",stdin); input() ; solve(); return 0; }
版权声明:博主表示授权一切转载:)
POJ 2965 The Pilots Brothers' refrigerator (想法题)
原文地址:http://blog.csdn.net/qq_15714857/article/details/47132611