http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5746

题目大意:

N*M的方格里,每个格子有一个指针,一开始指向上下左右四个方向中的一个,选一个格子点一次,那个格子的指针会顺时针转一下,接着被它指着的那个格子的针也会顺时针转一下,一直连锁下去。  构造一种不超过6000次点击的方案,使得所有针朝上。

题解:
$need[x][y]$表示这个格子的针转多少次可以朝上。

$A[x][y]$表示这个格子主动转了多少次。

$B[x][y]$表示这个格子由于受到边上格子的影响被动转了多少次。

那么有:

$A[x][y] + B[x][y] = 4 * K[x][y] + need[x][y]$. (等式1)

$B[x][y] = \sum (K[x'][y'] + [(x', y')转到朝上的过程中会影响到(x, y)]) $  (等式2)

其中$(x', y')是和(x, y)相邻的格子$

一开始先假设所有的 $K[x][y] = 0$,那么所有的$A[x][y]$ $B[x][y]$ 都可以计算出来。但是某些$A[x][y]$会是负数。

考虑把一些$K[x][y]$加大。 如果把$K[x][y] += 1$, 为了使得之前的等式仍然成立,必须有$A[x][y] += 4$,所有和它相邻的格子(x', y')必须 $A[x'][y'] -= 1, B[x'][y'] += 1$。

然后先本地开始乱shi:

因为不超过6000步,平均每个格子60步。

所以从上到下从左到右,如果发现当前格子的$A[x][y] <= 56$, 就不断让当前格子+4,和它相邻格子-1。

这样做一次后,发现最外面的一圈的$A[x][y]$都是几十了。中间的还是会有一些负数。

重复上面的过程,发现每做一次都会使得A为几十的圈子往里缩小。重复10次就ok了。

思考:为什么所有让$A[x][y]>=0$ 就好了呢?

因为一组合法的$A[x][y]$,可以解出所有的$B[x][y]$ 和 $K[x][y]$.且解是唯一的。

证明: 把等式1中的B用K表示带入等式二,得到$N^2$个关于$K$的方程,$K$有$N^2$个变量,所以如果有解,解一定唯一。

 #include <bits/stdc++.h>
using namespace std; #define MAXN 15 int n, m;
int a[MAXN][MAXN], x[MAXN][MAXN], y[MAXN][MAXN];
int dx[] = {-, , , };
int dy[] = {, , , -};
int ok[][], need[MAXN][MAXN]; bool check(int x, int y)
{
return x >= && x <= n && y <= m && y >= && a[x][y] != -;
} int main()
{
//freopen("in.txt", "r", stdin);
ok[][] = ;
ok[][] = ok[][] = ;
ok[][] = ok[][] = ok[][] = ; int T;
scanf("%d", &T);
while (T--)
{
scanf("%d %d", &n, &m);
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
{
scanf("%d", &a[i][j]);
if (a[i][j] == -) continue;
a[i][j] = ( - a[i][j]) % ;
need[i][j] = ( - a[i][j]) % ;
}
}
memset(x, , sizeof(x));
memset(y, , sizeof(y));
int _i, _j;
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
{
if (a[i][j] == -) continue;
for (int d = ; d < ; ++d)
{
_i = i + dx[d], _j = j + dy[d];
if (check(_i, _j) && ok[d][a[_i][_j]])
++y[i][j];
}
x[i][j] = need[i][j] - y[i][j];
}
}
int iters = ;
while (iters--)
{
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
{
if (a[i][j] == -) continue;
while (x[i][j] + <= )
{
x[i][j] += ;
for (int d = ; d < ; ++d)
{
_i = i + dx[d], _j = j + dy[d];
if (check(_i, _j)) --x[_i][_j], ++y[_i][_j];
}
}
}
}
}
vector<pair<int, int> > ans;
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
{
if (a[i][j] == -) continue;
assert(x[i][j] >= );
while (x[i][j] > ) --x[i][j], ans.push_back(make_pair(i, j));
}
}
printf("%d\n", ans.size());
for (int i = ; i < (int)ans.size(); ++i)
printf("%d %d\n", ans[i].first, ans[i].second);
} return ;
}

Crosses Puzzles zoj 4018 (zju校赛)的更多相关文章

  1. ZOJ 17届校赛 Knuth-Morris-Pratt Algorithm( 水题)

    In computer science, the Knuth-Morris-Pratt string searching algorithm (or KMP algorithm) searches f ...

  2. ZOJ 17届校赛 How Many Nines

    If we represent a date in the format YYYY-MM-DD (for example, 2017-04-09), do you know how many 9s w ...

  3. ZOJ 3955 Saddle Point 校赛 一道计数题

    ZOJ3955 题意是这样的 给定一个n*m的整数矩阵 n和m均小于1000 对这个矩阵删去任意行和列后剩余一个矩阵为M{x1,x2,,,,xm;y1,y2,,,,,yn}表示删除任意的M行N列 对于 ...

  4. ZJU 17th 校赛

    第一次参加校赛,和小伙伴们拿了7个气球,还是挺开心的.  简单记个流水账吧. A:判断出INF的情况后 暴力模拟即可. INF的情况有x=1 || y=1 || (x==2 && y= ...

  5. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  6. SCNU省选校赛第二场B题题解

    今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...

  7. 2014上半年acm总结(1)(入门+校赛)

    大一下学期才开始了acm,不得不说有一点迟,但是acm确实使我的生活充实了很多,,不至于像以前一样经常没事干=  = 上学期的颓废使我的c语言学的渣的一笔..靠考前突击才基本掌握了语法 寒假突然醒悟, ...

  8. 2017CUIT校赛-线上赛

    2017Pwnhub杯-CUIT校赛 这是CUIT第十三届校赛啦,也是我参加的第一次校赛. 在被虐到崩溃的过程中也学到了一些东西. 这次比赛是从5.27早上十点打到5.28晚上十点,共36小时,中间睡 ...

  9. HZNU第十二届校赛赛后补题

    愉快的校赛翻皮水! 题解 A 温暖的签到,注意用gets #include <map> #include <set> #include <ctime> #inclu ...

随机推荐

  1. Wpf修改控制的大小

    Wpf修改控制的大小 随窗体的改变而改变 在WINFORM中设置控件的Anchor属性就行了 在WPF中没有Anchor属性 但可以在布局中设置 相关属性实现同样的效果 相关属性 Horizontal ...

  2. 使用python语言编写脚本控制freeswitch总结

    1.  在Linux环境下已经安装了freeswitch,(没安装freeswitch,请安装说明文档) 2.  进入源代码目录 cd  libs/esl 目录下 首先安装 yum install p ...

  3. pip运行报错Fatal error in launcher: Unable to create process using pip.exe

    使用pip的时候报错Fatal error in launcher: Unable to create process using pip.exe 解决办法,升级pip python -m pip i ...

  4. 优秀运维人员20道必会iptables面试题(转载)

    (一)企业面试口试题 1.详述iptales工作流程以及规则过滤顺序? 2.iptables有几个表以及每个表有几个链? 3.iptables的几个表以及每个表对应链的作用,对应企业应用场景? 4.画 ...

  5. .NET Remoting与Socket、Webservice和WCF的比较及优势 (转)

    1:Socket VS Remoting 使用socket无疑是效率最高的.但是,在复杂的接口环境下,Socket的开发效率也是最低的.故在兼顾开发效率的情况下,可以使用Remoting来代替Sock ...

  6. Fiddler-抓取安卓手机APP请求地址

    第一步:下载神器Fiddler,下载链接: http://fiddler2.com/get-fiddler 下载完成之后,傻瓜式的安装一下了! 第二步:设置Fiddler打开Fiddler,     ...

  7. struts过滤器的原理

    struts就是充当拦截器(过滤器)的作用.在web.xml配置过滤器, package cn.itcast.framework.core; import java.io.IOException; i ...

  8. hudson status

    http://sin90lzc.iteye.com/blog/1072123在eclipse上显示hudson构建状态 update site:http://eclipse-plugin-potpou ...

  9. crc32 根据字符串获取校验值

    using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text; n ...

  10. 查询MySql数据库架构信息:数据库,表,表字段

    /*1.查询所有数据库*/ show databases;  /*2.查询所有数据表*/ select * from information_schema.tables where table_sch ...