sgu229:Divide and conquer(模拟+分析)

题目大意: 以及平移可以得到另一部分。(注意先翻转后平移)

分析: 刚开始看不懂题意,还以为翻转平移可以随便做,纠结了半天。。。 的格子上,,给这两个编号连边,由于每个点只会最多有一个前驱和后继,因此构出来的图只包含链与环。 如果是偶链,我们可以认为其中链上排名为奇数的点可以通过操作到偶数的点,如果是偶环类似。 很明显如果有奇环或奇链无解。 。

AC code:

MAXN = 29;int n;int g[MAXN][MAXN];int tot1;int to[MAXN*MAXN], fr[MAXN*MAXN];int ans[MAXN][MAXN];bool vis[MAXN*MAXN];std::pair<int,int> Map[MAXN*MAXN];bool inside(int x) {return x >= 1 && x <= n;}int main(){#ifndef ONLINE_JUDGEfreopen(“sgu229.in”, “r”, stdin);freopen(“sgu229.out”, “w”, stdout);#endifstd::ios::sync_with_stdio(0);std::cin >> n;for(int i = 1; i <= n; ++i)for(int j = 1; j <= n; ++j){char c;std::cin >> c;g[i][j] = c-‘0’;if(g[i][j]){g[i][j] = ++tot1;Map[tot1] = std::mp(i, j);}}if(tot1&1){std::cout << “NO” << std::endl;return 0;}for(int p = 0; p <= 3; ++p)for(int addx = -n; addx <= n; ++addx)for(int addy = -n; addy <= n; ++addy){memset(to, 0, sizeof(to));memset(fr, 0, sizeof(fr));memset(ans, 0, sizeof(ans));memset(vis, false, sizeof(vis));for(int x = 1; x <= n; ++x)for(int y = 1; y <= n; ++y)if(g[x][y]){int nx, ny;if(p == 0) nx = x, ny = y;else if(p == 1) nx = y, ny = n-x+1;else if(p == 2) nx = n-x+1, ny = n-y+1;else nx = n-y+1, ny = x;nx += addx, ny += addy;if(inside(nx) && inside(ny) && g[nx][ny]){if(x == nx && y == ny) goto next_option;int p = g[x][y], q = g[nx][ny];fr[q] = p, to[p] = q;}}for(int i = 1; i <= tot1; ++i)if(!vis[i] && !fr[i] && to[i]){int cnt = 0, j = i;while(j){if(!(cnt&1)) ans[Map[j].first][Map[j].second] = 1;vis[j] = true;j = to[j], ++cnt;}if(cnt&1) goto next_option;}for(int i = 1; i <= tot1; ++i)if(!vis[i]){int cnt = 0, j = i;while(!vis[j] && j){if(!(cnt&1)) ans[Map[j].first][Map[j].second] = 1;vis[j] = true;j = to[j], ++cnt;}if(cnt&1) goto next_option;}std::cout << “YES” << std::endl;for(int i = 1; i <= n; ++i){for(int j = 1; j <= n; ++j)std::cout << ans[i][j];std::cout << std::endl;}return 0;next_option:;}std::cout << “NO” << std::endl;#ifndef ONLINE_JUDGEfclose(stdin);fclose(stdout);;}

当我要取的时候,你淘气的躲开了,

sgu229:Divide and conquer(模拟+分析)

相关文章:

你感兴趣的文章:

标签云: