ZOJ3838 - Infusion Altar(找规律模拟)
来源:互联网 发布:linux 多进程 例子 编辑:程序博客网 时间:2024/05/17 22:08
【题目】
Bob is recently playing a game called Minecraft, especially a mod calledThaumcraft. It is a mod of magic.
Usually, Bob has Obsessions with Symmetry while playing Minecraft. This obsession is useless in the gameplay generally. However, inThaumcraft, the infusion altar requires symmetry to keep it stable.
Bob built an infusion altar in his secret chamber, but it was not so symmetrical. After some explosions, Bob decided to fix the infusion altar to make it symmetrical.
You will be given the map of Bob's secret chamber. It is of size n*n(n is an odd number), the infusion altar is always at the center of his secret chamber. The following picture is a typical map. The 3*3 square in the center is the Infusion Altar, it is a multi-block structure. Here, '#' means Runic Matrix, 'o' means Arcane Pedestal, '.' means an empty place, 'a'-'z' means occult paraphernalia(like skulls, crystals and candles) Bob placed around the Infusion Altar. There will not be characters other than 'a'-'z', '.', '#'.
.aab.bo.obb.#.abo.obbbab.
Now, the question is that at least how many blocks need to be changed to make the whole map symmetrical. Here, being symmetrical means having all four axes of symmetry for a square. Also, you can change any character on the map to any other character.
Input
There are multiple cases. The first line contains one integer T which is the number of test cases.
For each case, The first line contains an integer n ( 3 ≤ n ≤ 99, and n is an odd number)
For the next n lines, each line contains n characters showing the map.
It is guaranteed that the Infusion Altar is at the center of the map.
It is guaranteed that only 'a'-'z' and '.' will appear out of the Infusion Altar.
Output
One integer for each test case which is the least number of blocks that should be changed.
Sample Input
33o.o.#.o.o5.aab.bo.obb.#.abo.obbbab.5aabbaao.oaa.#.aao.oaaaaaa
Sample Output
032
Hint
The first sample is a standard Infusion Altar.
In second sample, Bob will change his secret chamber to the following map.
.bab.bo.oba.#.abo.ob.bab.
Author: ZHU, Jiale; GONG, Yuan
Source: ZOJ Monthly, November 2014
【分析】题目是求最少改变多少个格子使得棋盘满足4条对称轴都对称,比赛的时候就死在all four axes,不知道怎么了一直把axes看成是区域,唉不说了,心痛。
知道是需要4条对称轴对称就好办了
先画个7*7的图
4条对称轴如上,对于红色字1的格子,其实只有这红色这1~8有关系,与其他点没关联,这样我们只需枚举一个点,
然后考虑每个点所关联的8个点,在这8个点中求出让他们变成相同字符的最小变化次数,然后用vis标记出这遍历过的8个点,再枚举矩阵遍历没访问过的其他点。
问题在于如何通过一个点求出其他7个点的坐标,仔细观察可以先得出1~4点的关联:
假设1点坐标为(i,j),则2为(i,n-j-1),3:(n-i-1,j),4:(n-i-1,n-j-1);
通过这四个点可以推出其他4个点坐标分别为:
5(j,i) 6(n-j-1,i) 7(j,n-i-1) 8(n-j-1,n-i-1)
现在知道了坐标的计算,那么离解决不远了;
还有一个问题就是如何求出这8个点最小需要变化几次让他们都相同。
仔细观察,其实不难,我们记录下每个字符出现的次数,然后求出单个字符最多出现的次数mx,则8-mx就是答案,
但是对于在4条对称轴上的点需要特判,其实只要都除以就行,变成4-mx/2,因为他们只有4个点关联,除2蛆去重即可。
这样就解决了,个人认为代码还是蛮简洁的。
【AC CODE】0ms
#include <cstdio>#include <cstring>#include <cctype>#include <cmath>#include <map>//#include <unordered_map>#include <queue>#include <stack>#include <vector>#include <string>#include <algorithm>using namespace std;#define rep(i,a,n) for(int i = a; i < n; i++)#define repe(i,a,n) for(int i = a; i <= n; i++)#define per(i,n,a) for(int i = n; i >= a; i--)#define clc(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3ftypedef long long LL;int n;int get_sum(bool mid,char *a)//获得8个点最小变化次数{int vis[300]={0}, mx = 0;rep(i,0,8) vis[a[i]]++;int ans;repe(i,'a','z') mx = max(mx,vis[i]);mx = max(vis['.'],mx);mx = max(vis['#'],mx);if(mid) ans = 4-mx/2;else ans = 8-mx;return ans;}char a[110][110];int main(){#ifdef SHYfreopen("e:\\1.txt", "r", stdin);#endifint t;scanf("%d%*c", &t);while(t--){scanf("%d%*c", &n);rep(i,0,n)scanf("%s", a[i]);int ans = 0;int vis[110][110]={0};rep(i,0,n){rep(j,0,n){if(!vis[i][j]){char buf[9]={a[i][j],a[n-i-1][j],a[i][n-j-1],a[n-i-1][n-j-1],a[j][i],a[n-j-1][i],a[j][n-i-1],a[n-j-1][n-i-1]};buf[8] = 0;ans += get_sum((i == n/2 || j == n/2 || i == j || n-1 == i+j),buf);vis[i][j] = vis[n-i-1][j] = vis[i][n-j-1] = vis[n-i-1][n-j-1] = 1;vis[j][i] = vis[n-j-1][i] = vis[j][n-i-1] = vis[n-j-1][n-i-1] = 1;}}}printf("%d\n", ans);}return 0;}
- ZOJ3838 - Infusion Altar(找规律模拟)
- zoj 3838 Infusion Altar
- ZOJ-3838-Infusion Altar
- ZOJ 3838 Infusion Altar
- 【水题】 ZOJ 3838 Infusion Altar
- ZOJ 3838 Infusion Altar(数学啊 模拟啊 这么挫的代码你见过吗?)
- cf(找规律,模拟)
- HDU2147(模拟找规律)
- FZU1062(找规律+模拟)
- zoj3838浙大月赛 大模拟
- SGU 118. Digital Root 找规律+模拟
- FOJ 1062 洗牌问题 // 找规律,模拟
- Harmonic Number (II)(模拟找规律)
- HDU6130 Kolakoski 模拟|找规律|签到
- UVA679模拟小球降落(大数模拟超时是找规律)
- 找规律
- 找规律!
- 找规律
- 数据库索引简介
- 数据结构——动态链表(C++)
- 无备份情况下表空间损坏的恢复
- 并发计算模型BSP与SEDA
- 查看表空间使用情况sql语句
- ZOJ3838 - Infusion Altar(找规律模拟)
- Android利用SpannableStringBuilder设置TextView中部分文字的颜色...
- progressbar实现旋转
- Android自定义类似于QQ的消息提示框
- android 基本任务 的执行原理分析
- JSONObject与JSONArray的使用
- Android JSON 解析(二) JSONReader 和 JSONWriter
- 第二天 adb命令
- 流程技术