题目链接H-Harmonious Rectangle_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)

题目描述

A vertex-colored rectangle is a rectangle whose four vertices are all painted with colors. For a vertex-colored rectangle, it's harmonious if and only if we can find two adjacent vertices with the same color, while the other two vertices also have the same color with each other.

For example, , and are harmonious, while is not (same number for same color, and different numbers for different colors).

For each point in , where is the set of all integers, Kotori wants to paint it into one of the three colors: red, blue, yellow. She wonders the number of different ways to color them so that there exists at least one harmonious rectangle formed by the points, whose edges are all parallel to the - or -axis. That is to say, there exists and such that

or
where is the color of point .

Two coloring plans are considered different if there exists a point having different colors in the two coloring plans.

输入描述:

There are multiple test cases. The first line of the input contains an integer  () indicating the number of test cases. For each test case:

The first and only line contains three integers , ().

输出描述:

For each test case output one line containing one integer indicating the number of different ways of coloring modulo .
示例1

输入

复制 3 1 4 2 2 3 3

3
1 4
2 2
3 3

输出

复制 0 15 16485

0
15
16485

题目大意

给你一个n*m的矩阵,每个点都可以取三种颜色。问你有多少种染色方法可以使得矩阵中至少一对(x1,y1)与(x2,y2)满足下列式子。

(a[y1][x1] == a[y2][x1] && a[y1][x2] == a[y2][x2]) ||
(a[y1][x1] == a[y1][x2] && a[y2][x1] == a[y2][x2]))

分析

考虑在矩阵中选择任意两行a和b

a1 a2 a3 a4 a5 a6 ......
b1 b2 b3 b4 b5 b6 ......

可知(a1,b1)有3*3=9种组合方式。根据鸽笼原理,或者直接动脑子想想,可以想到当列数>9时,一定存在另一组(ai,bi)与(a1,b1)相同。同理,当行数>9时,一定存在两组相同的列。所以可以分类讨论:

  • if n=1 || m=1 ,必为0
  • else if n>9 || m>9,结果为3n∗m3^{n*m}3n∗m
  • else 在9*9范围内,可以DFS剪枝搜索,然后把结果打个表。

打表用代码

分别用DFS剪枝和暴力穷举法实现。后者用来与前者在小范围时对拍。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;ll mod_mul(ll a, ll b, ll n) {a %= n;  //优化后只要在开头模一次,其他的地方用if,效率提升近一倍b %= n;ll res = 0;while (b) {if (b & 1) {res += a;if (res > n) res -= n;}a += a;if (a > n) a -= n;b /= 2;  //没开o2的话要换成b>>=1}return res;
}ll mod_exp(ll a, ll b, ll n) {ll res = 1;a = a % n;while (b) {if (b & 1) res = mod_mul(res, a, n);a = mod_mul(a, a, n);b /= 2;}return res;
}const ll MOD = 1e9 + 7;
const int MAXN = 12;
int a[MAXN][MAXN];
int n, m;
long long gcnt;void get_next() {const static int base = 3;int carry = 1;for (int i = n - 1; i >= 0; i--) {for (int j = m - 1; j >= 0; j--) {a[i][j] += carry;carry = 0;if (a[i][j] >= base) {carry = a[i][j] / base;a[i][j] %= base;}}}
}void print() {for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {printf("%d ", a[i][j]);}printf("\n");}printf("\n");
}bool check() {for (int y1 = 0; y1 < n; y1++) {for (int x1 = 0; x1 < m; x1++) {for (int y2 = y1 + 1; y2 < n; y2++) {for (int x2 = x1 + 1; x2 < m; x2++) {if ((a[y1][x1] == a[y2][x1] && a[y1][x2] == a[y2][x2]) ||(a[y1][x1] == a[y1][x2] && a[y2][x1] == a[y2][x2]))return true;}}}}return false;
}void dfs(int xx, int yy) {for (int color = 0; color < 3; color++) {int x2 = xx;int y2 = yy;a[y2][x2] = color;bool flag = true;for (int y1 = 0; y1 < y2 && flag; y1++) {for (int x1 = 0; x1 < x2 && flag; x1++) {if ((a[y1][x1] == a[y2][x1] && a[y1][x2] == a[y2][x2]) ||(a[y1][x1] == a[y1][x2] && a[y2][x1] == a[y2][x2])) {flag = false;gcnt +=mod_exp(3LL, (1LL * (n - 1 - y2) * (m) + (m - 1) - x2), MOD);gcnt %= MOD;}}}if (flag) {x2++;if (x2 >= m) {x2 = 0;y2++;if (y2 >= n){continue;}}dfs(x2, y2);}}a[yy][xx]=-1;
}ll solve_dfs(){gcnt=0;dfs(0,0);return gcnt;
}int solve_exhaust() {int p = pow(3, n * m);int cnt = 0;for (int i = 0; i < p; i++) {if (check()) {cnt++;// print();}// print();get_next();}return cnt;
}int main() {for(n =1; n<=9;n++){for(m=1;m<=9;m++){if(m==1||n==1) printf("0, ");else{memset(a,0,sizeof(a));printf("%lld, ",solve_dfs());//printf("%lld, ",solve_exhaust());}}printf("\n");}return 0;}

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9+7;
int n,m;ll mod_mul(ll a, ll b, ll n) {a %= n;  //优化后只要在开头模一次,其他的地方用if,效率提升近一倍b %= n;ll res = 0;while (b) {if (b & 1) {res += a;if (res > n) res -= n;}a += a;if (a > n) a -= n;b /= 2;  //没开o2的话要换成b>>=1}return res;
}ll mod_exp(ll a, ll b, ll n) {ll res = 1;a = a % n;while (b) {if (b & 1) res = mod_mul(res, a, n);a = mod_mul(a, a, n);b /= 2;}return res;
}ll dat[9][9]={0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 15, 339, 4761, 52929, 517761, 4767849, 43046721, 387420489,
0, 339, 16485, 518265, 14321907, 387406809, 460338013, 429534507, 597431612,
0, 4761, 518265, 43022385, 486780060, 429534507, 792294829, 175880701, 246336683,
0, 52929, 14321907, 486780060, 288599194, 130653412, 748778899, 953271190, 644897553,
0, 517761, 387406809, 429534507, 130653412, 246336683, 579440654, 412233812, 518446848,
0, 4767849, 460338013, 792294829, 748778899, 579440654, 236701429, 666021604, 589237756,
0, 43046721, 429534507, 175880701, 953271190, 412233812, 666021604, 767713261, 966670169,
0, 387420489, 597431612, 246336683, 644897553, 518446848, 589237756, 966670169, 968803245};int main() {int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);if(n==1||m==1){printf("0\n");}else if(n<=9||m<=9){n--;m--;printf("%lld\n",dat[n][m]%MOD);}else{printf("%lld\n",mod_exp(3,1LL*n*m,MOD));}}return 0;
}

参考资料

2020年ICPC南京区域赛题解 - 知乎

2020 ICPC 南京 H Harmonious Rectangle (DFS剪枝+思维)相关推荐

  1. 2020 ICPC 南京站 M Monster Hunter (树形DP)

    题目链接:M-Monster Hunter_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京) 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5 ...

  2. 2020 ICPC 南京站 F Fireworks (概率论+三分)

    题目链接:F-Fireworks_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京) 题目描述 Kotori is practicing making fireworks for the ...

  3. 容斥 + 爆搜打表 ---- 2020年南京icpc H.Harmonious Rectangle

    题目链接 题目大意: 就是给你一个二维平面{(x,y)∣1≤x≤n,1≤y≤m}\{(x,y)|1\leq x\leq n,1\leq y \leq m\}{(x,y)∣1≤x≤n,1≤y≤m},你现 ...

  4. 树形dp --- 2020 icpc 南京 M Monster Hunter

    题目链接 题目大意: 解题思路: 首先我们分析一下每个点状态是怎么? 1.1: 对于这个点我们删除的代价我们要看一下它儿子有多少个没被删除(指没用)因为父亲节点没删这个点呀删除不了 1.2: 那么这个 ...

  5. Fireworks(2020 ICPC南京)

    Fireworks 题意: 你每做一个烟花要n分钟,释放已做好的所有烟花需要m分钟,每只烟花成功释放的概率为p.问你在采取最优策略的前提下,直到成功释放第一个烟花时最小的期望时间花费. 题解: 最佳策 ...

  6. 组合计数 ---- 2020 icpc 上海 The Journey of Geor Autumn(思维划分问题计数+预处理优化)

    题目链接 题目大意: 就是你有一个nnn的全排列,现在问你去重排这个排列使得对于给定的kkk,满足对于任意的ai,i>ka_i,i>kai​,i>k的都有ai>min(ai−1 ...

  7. 2021 ICPC 南京 3.27训练赛

    2021 ICPC 南京 D - Paimon Sorting J - Xingqiu's Joke I - Cloud Retainer's Game 题目链接 D - Paimon Sorting ...

  8. 2020 ICPC Macau A. Accelerator(期望,计数,分治FFT)(每日一题 21.7.6)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2020 ICPC Macau A. Accelerator(分治FFT) Problem 给定长度为 ...

  9. POJ2688状态压缩(可以+DFS剪枝)

    题意:       给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路:       水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...

最新文章

  1. PMCAFF微课堂 | 京东零售平台资深PM深度揭秘京东的订单体系
  2. Oracle中大批量删除数据的方法
  3. ❤️六W字《计算机基础知识》(一)(建议收藏)❤️
  4. codeforces 768 C. Jon Snow and his Favourite Number(思维+暴力)
  5. 算法分析-动态规划-01背包
  6. cartographer探秘之文章索引
  7. flash player 10 beta已经放出
  8. vue + echarts 实现以中国为中心的世界3D地图
  9. signature=99daf37ca32015c39987d04abe5a559d,合肥2015年7月4日至2015年7月16日交通违章查询...
  10. 慕课网C#开发轻松入门 6-1练习题目
  11. 上海交通大学计算机科学与技术招生网,上海交通大学计算机科学与技术研究生招生...
  12. android滑屏效果,Android使用ViewFlipper和GestrueDetector共同实现滑屏效果实例
  13. 利用ps生成闪电特效
  14. java多线程 isAlive方法的有趣现象
  15. 百度云盘下载jdk1.8
  16. Python函数部分2
  17. 【C语言进阶17——程序环境和预处理】
  18. 下载土豆视频——像个极客那样
  19. 无忧启动E源码 仿音速启动
  20. 【2016年总结】-- 你若盛开,清风自来

热门文章

  1. 【疑难杂症】Oculus Quest2 手机配对时找不到5-digit-code
  2. 用c语言写一个自动售货机
  3. Windows7正式版默认壁纸暗藏玄机!
  4. grab显示服务器报错,grab链接不到服务器怎么解决
  5. 抖音跳转微信小卡片怎么做不封号
  6. HTNL常见的标签及属性 和w3school的使用
  7. ipad/ios按钮背景颜色为渐变色?去除iOS按钮渐变色
  8. 腾讯云老用户重新注册新账号算新用户吗?
  9. 网店工商信息图片文字提取
  10. 灭霸只是开始 看数字王国的虚拟版图