您的位置:首页 > 其它

[CodeForces 126C]E-reader Display[实现]

2016-03-14 00:10 211 查看
题目链接:[CodeForces 126C]E-reader Display[实现]
题意分析:

给出一张图,让你用最短的步骤描绘出这张图,输出最短步骤数。

(x,y)代表将区间(x,x)~(x,y)和区间(x,y)~(y,y)的线段0变1,1变0。

解题思路:

从一个点可以染色的区间我们可以发现啊(举右上方为例子):这个点能控制的只有它的左平行线和下方垂直线。而且你会发现啊,一个点染色过一次,重新再在这个点染色是浪费的。由上方结论,我们可以得出策略:从右上方开始遍历,如果这个点要染色,就把这个点给染色了(因为后期再也没有点可以给它染色了),然后接着往左,发现,这个点不需要染色,可是被我们的右方点染色了,所以我们就把它染回来。(建议画个图,还是蛮好理解的;)

如果单纯记录染色和不染色,这样更新下去,整个复杂度n^3,所以我们设数组来记录行和列是否被染色即可,复杂度n^2。

个人感受:

瞎搞啊,没想到还真是这规律,哈哈哈

具体代码如下:

#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<string>
#define ll long long
#define pr(x) cout << #x << " = " << (x) << '\n';
using namespace std;

const int INF = 0x7f7f7f7f;
const int MAXN = 2e3 + 111;

char s[MAXN][MAXN];
// a:右上方 b:左下方。举个例子:ar[i]代表从这个点往左的行是否被染色,其它同
bool ar[MAXN], ac[MAXN], br[MAXN], bc[MAXN];

int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) scanf("%s", s[i]);

int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = n - 1; j > i; --j) {
if (s[i][j] == '1' && ar[i] + ac[j] != 1) {
ar[i] ^= 1;
ac[j] ^= 1;
++ans;
}
else if (s[i][j] == '0' && ar[i] + ac[j] == 1) {
ar[i] ^= 1;
ac[j] ^= 1;
++ans;
}
}
}
for (int i = n - 1; i >= 0; --i) {
for (int j = 0; j < i; ++j) {
if (s[i][j] == '1' && br[i] + bc[j] != 1) {
br[i] ^= 1;
bc[j] ^= 1;
++ans;
}
else if (s[i][j] == '0' && br[i] + bc[j] == 1) {
br[i] ^= 1;
bc[j] ^= 1;
++ans;
}
}
}
for (int i = 0; i < n; ++i) {
int x = bc[i] + br[i] + ac[i] + ar[i];
if (s[i][i] == '1' && x % 2 == 0) ++ans;
else if (s[i][i] == '0' && x % 2) ++ans;
}

printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: