[hdu5319]二进制表示,简单模拟
题意:给一个矩形,矩形里面画了4种符号,'.'表示没画线,'R'表示画了红线,'B'表示画了蓝线,'G'表示红线和蓝线同时画了,并且矩形主对角线上只能画红线,副对角线上只能画蓝线,问最少画多少条线才能形成给定的矩形的涂色情况。
思路:实际上给定的矩形唯一对应一种画线图案,'.'对应的格子没任何线,'R'对应的格子只有一条左上至右下的线,'B'对应的格子只有一条左下至右上的线,'G'对应的格子左上至右下、左下至右上都有线,那么问题转化为求最后的线条图案形成了多少线段。具体来说,只需要对每条对角线(包括主副)都从前之后扫一遍,如果对角线方向有线而它的前一个没这种方向的线或者它本身是第一个的话,答案加1。个人觉得用2位二进制来表示这种状态比较优雅。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /* ******************************************************************************** */ #include <iostream> // #include <cstdio> // #include <cmath> // #include <cstdlib> // #include <cstring> // #include <vector> // #include <ctime> // #include <deque> // #include <queue> // #include <algorithm> // using namespace std; // // #define pb push_back // #define mp make_pair // #define X first // #define Y second // #define all(a) (a).begin(), (a).end() // #define foreach(i, a) for (typeof(a.begin()) it = a.begin(); it != a.end(); it ++) // // void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);} // void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R> // void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1; // while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T> // void print( const T t){cout<<t<<endl;} template < typename F, typename ...R> // void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T> // void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;} // // typedef pair< int , int > pii; // typedef long long ll; // typedef unsigned long long ull; // // /* -------------------------------------------------------------------------------- */ // template < typename T> bool umax(T &a, const T &b) { return a >= b? false : (a = b, true ); } int a[123][123]; char s[123]; int main() { #ifndef ONLINE_JUDGE freopen ( "in.txt" , "r" , stdin); #endif // ONLINE_JUDGE int T; cin >> T; while (T --) { int n, m; RI(n); memset (a, 0, sizeof (a)); for ( int i = 1; i <= n; i ++) { scanf ( "%s" , s); m = strlen (s); for ( int j = 0; j < m; j ++) { if (s[j] == '.' ) continue ; a[i][j + 1] = s[j] == 'R' ? 1 : (s[j] == 'B' ? 2 : 3); } } n = max(n, m); int ans = 0; for ( int i = 1; i <= n; i ++) { for ( int j = 1; j <= i; j ++) { if (a[i - j + 1][j] & 2) { if (!(a[i - j + 2][j - 1] & 2)) ans ++; } } } for ( int i = 2; i <= n; i ++) { for ( int j = i; j <= n; j ++) { if (a[n - j + i][j] & 2) { if (!(a[n - j + i + 1][j - 1] & 2)) ans ++; } } } for ( int i = 1; i <= n; i ++) { for ( int j = i; j <= n; j ++) { if (a[j - i + 1][j] & 1) { if (!(a[j - i][j - 1] & 1)) ans ++; } } } for ( int i = 2; i <= n; i ++) { for ( int j = 1; j <= n - i + 1; j ++) { if (a[i + j - 1][j] & 1) { if (!(a[i + j - 2][j - 1] & 1)) ans ++; } } } cout << ans << endl; } return 0; // } // // // // /* ******************************************************************************** */ |