Solution

首先我们要有敏锐的直觉: 我们将每一列中不选哪种颜色看作是一个序列, 则我们发现这个序列要求相邻两位的颜色不同. 我们还发现, 一个这样的序列对应两种不同的合法的棋盘, 因此统计合法棋盘数的问题, 就转化为了统计合法序列数.

我们不妨设\(R > G > B\). 我们可以用R将这个序列切成\(R - 1\)或\(R\)或\(R + 1\)段, 这取决于序列的开头/结尾是否放R. 一旦确定了序列开头和结尾是否放R, 我们在后面就只考虑在序列中间放R, 而不考虑开头和结尾. 每一段由G和B交错组成. 我们将这些由G和B组成的段分为以下三类:

  • GBGBGB...GB 或 BGBGBG...BG, 即B的个数与G的个数相同. 我们记这样的段有\(x\)段.
  • GBGB...GBG, 即G的个数比B多\(1\). 我们记这样的段有\(y\)段.
  • BGBG...BGB, 即B的个数比G多1. 我们记这样的段有\(z\)段.

则我们发现\(y - z\)的值是固定的: \(y - z = G - B\).

我们假设\(R\)将该序列分为\(d\)段(根据前文, \(或或d = R - 1或d = R + 1或d = R\)), 则\(x + y + z = d\). 我们再枚举\(x\), 则\(y\)与\(z\)的数量也被确定了. 我们把第二和第三种情况的序列补全为G和B数量相等的情况, 则现在我们总共有\(\frac{G + B + y + z}{2}\)对GB或BG.

我们用插板法在这些BG或GB中插入\(d - 1\)个R即可.

#include <cstdio>
#include <algorithm>using namespace std;
const int M = (int)1e6, MOD = (int)1e9 + 7;
int pw[M + 1], fac[M + 1], facInv[M + 1];
inline int C(int a, int b)
{if (a < b) return 0;return (long long)fac[a] * facInv[a - b] % MOD * facInv[b] % MOD;
}
inline int getInverse(int a)
{int res = 1;for (int x = MOD -  2; x; a = (long long)a * a % MOD, x >>= 1) if (x & 1) res = (long long)res * a % MOD;return res;
}
inline int work(int d, int x, int y)
{int ans = 0;for (int a = 0; a <= d - (x - y); ++ a) if (((d - a) - (x - y)) % 2 == 0){int c = ((d - a) - (x - y)) / 2, b = x - y + c;ans = (ans + (long long)C((x + y + b + c) / 2 - 1, d - 1) * C(d, a) % MOD * C(b + c, b) % MOD * pw[a] % MOD) % MOD;}return ans;
}
int main()
{#ifndef ONLINE_JUDGEfreopen("board.in", "r", stdin);freopen("board.out", "w", stdout);#endifpw[0] = 1; for (int i = 1; i <= M; ++ i) pw[i] = pw[i - 1] * 2 % MOD;fac[0] = facInv[0] = 1; for (int i = 1; i <= M; ++ i) fac[i] = (long long)fac[i - 1] * i % MOD, facInv[i] = getInverse(fac[i]);int T; scanf("%d", &T);for (int cs = 0; cs < T; ++ cs){int m, R, G, B; scanf("%d%d%d%d", &m, &R, &G, &B);R = m - R; G = m - G; B = m - B;if (G < B) swap(G, B);if (R < G) swap(R, G);if (G < B) swap(G, B);int ans = (long long)2 * ((long long)work(R - 1, G, B) + 2 * work(R, G, B) + work(R + 1, G, B)) % MOD;printf("%d\n", ans);}
}

转载于:https://www.cnblogs.com/ZeonfaiHo/p/7592092.html

NOI模拟题4 Problem C: 填格子(board)相关推荐

  1. Gym 100646 Problem C: LCR 模拟题

    Problem C: LCR 题目连接: http://codeforces.com/gym/100646/attachments Description LCR is a simple game f ...

  2. I'm stuck! ccf模拟题。

    ccf模拟题. I'm stuck! 时间限制: 1.0s 内存限制: 256.0MB 问题描述 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S' ...

  3. POJ 3030 Nasty Hacks (模拟题)

    题目:http://poj.org/problem?id=3030 思路:模拟题 #include <iostream>using namespace std;int main() {in ...

  4. URAL 1993 This cheeseburger you don't need 模拟题

    This cheeseburger you don't need 题目连接: http://acm.timus.ru/problem.aspx?space=1&num=1993 Descrip ...

  5. CSP认证201612-3 权限查询[C++题解]:模拟题、结构体、set、有点复杂

    题目分析 来源:acwing 分析:这样的模拟题,主要难在建模,需要思考用什么来存储. 这里用一个结构体来存权限.用哈希表来存<角色,权限结构体>的映射,当然权限结构体存在set中,需要去 ...

  6. 2014c语言二级考试题,2014计算机二级等级考试试题:C语言模拟题

    ((1)-(10)每小题2分,(11)-(50)每题1分,共60分) 一 .下列各题A.B.C.D四个选项中,只有一个选项是正确的,请将正确选项涂写在答题卡相应位置上,答在试卷上不得分. (1)下列叙 ...

  7. 2011年全国软件大赛模拟题及参考答案(Java高职组)

    2011年全国软件大赛模拟题及参考答案(Java高职组) 不是官方的答案,如有不妥,请指出. 2011 模拟 java 高职 注意: 本套模拟题主要模拟命题形式与考核范围.真实竞赛题的数量.难度可能与 ...

  8. 2011年全国软件大赛模拟题及参考答案(Java本科组)

    非官方标注答案,如有不妥,请指出. 2011 模拟 java 本科 注意: 本套模拟题主要模拟命题形式与考核范围.真实竞赛题的数量.难度可能与此套模拟题有差异. 说明: 本试卷包含两种题型:" ...

  9. Codeforces Beta Round #5 B. Center Alignment 模拟题

    B. Center Alignment 题目连接: http://www.codeforces.com/contest/5/problem/B Description Almost every tex ...

最新文章

  1. Xilinx FPGA的配置
  2. 多模型融合(相当于投票)
  3. java并发编程详解,Java架构师成长路线
  4. Web 文件管理器elFinder 的漏洞链分析
  5. Insert Data into Sorted Table
  6. 大话数据结构与算法:基础篇
  7. 如何采集病变脏器照片和处理图像?
  8. 模板匹配(Match Template)
  9. 定了!这个专业研究生扩招,博士生待遇要提高!已有多所高校新增…
  10. 谁说大学生找工作难?鄙视说这样话的人!!
  11. java排错_java排错之CPU高
  12. java.io.IOException: output.properties data exceeds its limit [2048] hue的调度
  13. Matlab Tricks(二十五) —— 二维图像的 shuffle
  14. 【解决】Windows Mobile 6 Professional SDK Refresh.msi 在xp上一直卡死
  15. 资管新规 2018年4月27日
  16. oracle显示连接超时,Oracle 12179:tns:连接超时的问题
  17. 罗技K375s重新配置和连接
  18. 【React Native】使用react-native-wechat 进行微信好友、微信朋友圈进行分享
  19. Android源码下载教程
  20. 苹果ipad怎么用计算机来唱歌,‎App Store 上的“唱歌-教您怎么唱歌”

热门文章

  1. 【收藏】mydockfinder下载地址
  2. sqlplus远程连接k8s集群部署的oracle
  3. Linux shell脚本中单双引号的区别
  4. Hystrix和ribbon的超时时长准确配置的理论依据
  5. spring AOP注解含义
  6. 注定不平凡的2020年
  7. QML 实现图片帧渐隐渐显轮播
  8. Matlab---傅里叶变换---通俗理解(二)
  9. 强化学习5——价值函数近似(VFA)
  10. 《MySQL必知必会》所有SQL语句图表集合(可作为查询表使用)---已完结