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. Android AES加密算法及其实现

    找到了AES加密算法.(当然还有MD5,BASE64什么的http://snowolf.iteye.com/blog/379860这篇文章列举了很多,但是基本都是j2se平台的,android平台不一 ...

  2. 如何使用angularjs实现按钮事件

    <!DOCTYPE html> <html ng-app="myApp"> <head> <title>angularjs-setV ...

  3. ant Select 联动

    1.代码 /** * 选择监区 组件 */ import React, { PureComponent } from 'react'; import PropTypes from 'prop-type ...

  4. 创建win32窗口

    #include <windows.h> LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM); int WINAPI WinMain(HIN ...

  5. 使用原生js将轮播图组件化

    代码地址如下:http://www.demodashi.com/demo/11316.html   这是一个轮播图组件,这里是代码地址,需要传入容器的id和图片地址,支持Internet Explor ...

  6. Android View Attributes

    ImageView android:adjustViewBounds  Set this to true if you want the ImageView to adjust its bounds ...

  7. js 时间对比

    https://www.cnblogs.com/xiangsj/p/7977325.html http://www.jb51.net/article/45560.htm isOverdue (time ...

  8. django学习笔记【002】创建第一个django app

    2.3.3 1.创建一个名叫polls的app python3. manage.py startapp polls tree mysite/ mysite/ ├── db.sqlite3 ├── ma ...

  9. ES6中的export,import ,export default

    ES6模块主要有两个功能:export和importexport用于对外输出本模块(一个文件可以理解为一个模块)变量的接口import用于在一个模块中加载另一个含有export接口的模块.也就是说使用 ...

  10. 【进程线程与同步】5.4 System.Threading.Interlocked 为多个线程共享的变量提供原子操作

    using System; using System.Threading; internal class Program { private static long _counter = 1; pri ...