• Tsinsen-A1488 : 魔法波【高斯消元+异或方程组】


      高斯消元。

      自己只能想出来把每一个点看成一个变量,用Xi表示其状态,这样必定TLE,n^2 个变量,再加上3次方的高斯消元(当然,可以用bitset压位)。

      正解如下:

        我们把地图划分成一个个的横条和竖条,对于点i,我们用Li,Ri分别表示横着和竖着穿过它的,显然,对于每一个点,有且仅有一个L块和R块穿过。

        得到第一个方程    YLi = sigma(Xp) p属于Li,YRi = sigma(Xp) p属于Ri --> sigma(Xp) xor Yi = 0.

        接着我们考虑, Si xor YLi xor YRi xor Xi = 1 这是第二个方程,对其移项,那么变成了 Xi = 1 xor Si xor YLi xor YRi.

        将其回带到第一个式子中即可,对于每一个点,放在不同的两个方程里,一个横的,一个竖的即可。

      TLE50 我将枚举自由变量的语句删除后,发现没有TLE了,但是最多只有2000个障碍物,最多是O(2000^2)的复杂度,可能是数据加强了吧。

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define REP(i, a, b) for (int i = a; i < b; i++)
     4 #define drep(i, a, b) for (int i = a; i >= b; i--)
     5 #define pb push_back
     6 #define mp make_pair
     7 #define clr(x) memset(x, 0, sizeof(x));
     8 #define xx first
     9 #define yy second
    10 using namespace std;
    11 typedef long long i64;
    12 typedef pair<int, int> pii;
    13 const int inf = ~0U>>1;
    14 const i64 INF = ~0ULL>>1;
    15 //***************************
    16 const int maxn = 805;
    17 char ma[maxn][maxn];
    18 pii no[maxn][maxn];
    19 int n, cnt_x, cnt_eq;
    20 bitset<2005> eq[2005];
    21 void init() {
    22     rep(i, 1, n) {
    23         if (ma[i][1] != 'X') no[i][1].xx = ++cnt_x;
    24         rep(j, 2, n) {
    25             if (ma[i][j] == 'X') continue;
    26             if (no[i][j - 1].xx) no[i][j].xx = no[i][j - 1].xx;
    27             else no[i][j].xx = ++cnt_x;
    28         }
    29     }
    30     rep(i, 1, n) {
    31         if (ma[1][i] != 'X') no[1][i].yy = ++cnt_x;
    32         rep(j, 2, n) {
    33             if (ma[j][i] == 'X') continue;
    34             if (no[j - 1][i].yy) no[j][i].yy = no[j - 1][i].yy;
    35             else no[j][i].yy = ++cnt_x;
    36         }
    37     }
    38     cnt_eq = cnt_x;
    39     rep(i, 1, cnt_x) eq[i].set(i);
    40     rep(i, 1, n) rep(j, 1, n) if (no[i][j].xx) {
    41         int l = no[i][j].xx, r = no[i][j].yy;
    42         eq[l].flip(l), eq[l].flip(r), eq[r].flip(l), eq[r].flip(r);
    43         if (1 ^ (ma[i][j] - '0')) eq[l].flip(cnt_x + 1), eq[r].flip(cnt_x + 1);
    44     }
    45 }
    46 void gauss() {
    47     rep(i, 1, cnt_x) {
    48         rep(j, i, cnt_eq) if (eq[j][i] > eq[i][i]) { swap(eq[j], eq[i]); break; }
    49         rep(j, 1, cnt_eq) if (i != j && eq[j][i]) eq[j] ^= eq[i];
    50     }
    51 }
    52 int choice[2005];
    53 int main() {
    54     scanf("%d", &n);
    55     rep(i, 1, n) scanf("%s", ma[i] + 1);
    56     init();
    57     gauss();
    58     drep(i, cnt_x, 1) {
    59         if (eq[i][i]) {
    60             choice[i] = eq[i][cnt_x + 1];
    61             drep(j, cnt_x, i + 1) if (eq[i][j]) choice[i] ^= choice[j];
    62         }
    63         else choice[i] = 0;
    64     }
    65     rep(i, 1, n) {
    66         rep(j, 1, n) 
    67             if (ma[i][j] == 'X') printf("0");
    68             else printf("%d", 1 xor (ma[i][j] - '0') xor choice[no[i][j].xx] xor choice[no[i][j].yy]);
    69         puts("");
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    移动 App 接入 QQ 登录/分享 图文教程
    Word 最后一页无法删除-解决办法
    Java快速入门-04-Java.util包简单总结
    Java快速入门-03-小知识汇总篇(全)
    SSM 框架-06-详细整合教程(IDEA版)(Spring+SpringMVC+MyBatis)
    二叉树的镜像
    浅析I/O模型及其设计模式
    远程方法调用(RMI)原理与示例
    树的子结构
    合并两个排序的链表
  • 原文地址:https://www.cnblogs.com/y7070/p/5025816.html
Copyright © 2020-2023  润新知