Codeforces #777 题解

这次带上了大佬前来验题xs

公开大佬珍贵的代码资源供参考


TOC

  • A.Madoka and Math Dad
  • B.Madoka and the Elegant Gift
  • C.Madoka and Childish Pranks
  • D.Madoka and the Best School in Russia

A.Madoka and Math Dad

Problem

在给定条件下要找到最大的数字,考虑到数字位数较多的方案更优

由于不能使用0,也不能出现相邻的相同数字,因此使用1|2序列构造即可得到答案

首先令 ans=n3∗′21′ans= \frac{n}{3} * '21'ans=3n​∗′21′ ,进行分类讨论

  • n=0(mod3)n=0 \pmod{3}n=0(mod3) 则ans即为答案
  • n=1(mod3)n=1 \pmod{3}n=1(mod3) 则 ans=′1′+ansans='1'+ansans=′1′+ans
  • n=2(mod3)n=2 \pmod{3}n=2(mod3) 则 ans=ans+′2′ans=ans+'2'ans=ans+′2′

cpp-version

int t,n;
inline void Main()
{cin>>t;while(t--){cin>>n;string ans="";rep(i,1,n/3)ans+="21";if(n%3==1)ans="1"+ans;if(n%3==2)ans=ans+"2";cout<<ans<<endl;}return;
}

python3-version

n = int(input())
num_list = []
cnt = 0
while cnt < n:num_list.append(int(input()))cnt += 1
for num in num_list:res = num % 3mul = int(num / 3)if res == 0:print(mul * "21")elif res == 1:print("1" + mul * "21")else:print(mul * "21" + "2")

B.Madoka and the Elegant Gift

Problem

根据题目给出的定义,nice矩形即为某个不能再扩张的最大全1矩形

分析可以发现,如果某一片连续的全1区域不是规则的矩形,即这篇区域是在矩形的基础上增加了一些1方格,则该区域一定可以找到至少两个nice矩形相交

简单的例子:

[110111110]→[11∗11∗11∗]and[∗∗∗111∗∗∗]\begin{bmatrix} 1 & 1 & 0 \\ 1 & 1 & 1 \\ 1 & 1 & 0 \end{bmatrix} \rightarrow \begin{bmatrix} 1 & 1 & * \\ 1 & 1 & * \\ 1 & 1 & * \end{bmatrix} and \begin{bmatrix} * & * & * \\ 1 & 1 & 1 \\ * & * & * \end{bmatrix} ⎣⎡​111​111​010​⎦⎤​→⎣⎡​111​111​∗∗∗​⎦⎤​and⎣⎡​∗1∗​∗1∗​∗1∗​⎦⎤​

可以推广到更复杂的情况

结论:某个01矩阵是elegant的,当且仅当矩阵中的1方格构成了若干个规则的矩形

因此只需要判断矩阵中的1区域是否为标准的矩形即可

对于每一个1方格,分别向右向下搜索找到最长连续的1,作为当前子矩阵的n与m。只需要判断:

  • 子矩阵中是否全1
  • 子矩阵的边界是否存在1

即可得到当前子矩阵的合法性。对所有遍历过的1方格打标记,防止多次遍历

cpp-version

int t,n,m;
char A[200][200];
int mark[200][200];
inline bool check(int si,int sj)
{int nown=0,nowm=0;while(si+nown<=n&&A[si+nown][sj]=='1')++nown;while(sj+nowm<=m&&A[si][sj+nowm]=='1')++nowm;rep(i,si,si+nown-1)rep(j,sj,sj+nowm-1){if(A[i][j]=='0')return false;mark[i][j]=1;}rep(i,si,si+nown-1){if(sj-1>=1&&A[i][sj-1]=='1')return false;if(sj+nowm<=m&&A[i][sj+nowm]=='1')return false;}rep(j,sj,sj+nowm-1){if(si-1>=1&&A[si-1][j]=='1')return false;if(si+nown<=n&&A[si+nown][j]=='1')return false;}return true;
}
inline void Main()
{cin>>t;while(t--){cin>>n>>m;rep(i,1,n)rep(j,1,m){cin>>A[i][j];mark[i][j]=0;}bool flag=true;rep(i,1,n)rep(j,1,m){if(A[i][j]=='0'||mark[i][j]==1)continue;if(!check(i,j))flag=false;}if(flag)cout<<"Yes"<<endl;else cout<<"No"<<endl;}return;
}

python3-version

n = int(input())
ans_list = []cnt = 0while cnt < n:table = []tmp = input().split(' ')rows = int(tmp[0])cols = int(tmp[1])for row in range(rows):table.append([])num_str = str(input())for num in num_str:table[row].append(int(num))mark = []for row in range(rows):mark.append([])for col in range(cols):mark[row].append(0)def checkLen(r, c):cnt_col = 0while c + cnt_col <= cols - 1 and table[r][c + cnt_col] == 1:cnt_col += 1cnt_row = 0while r + cnt_row <= rows - 1 and table[r + cnt_row][c] == 1:cnt_row += 1return cnt_row, cnt_colrlen = 0clen = 0f = 0for row in range(rows):for col in range(cols):if table[row][col] == 0:continueif mark[row][col] == 0:rlen, clen = checkLen(row, col)for i in range(rlen):for j in range(clen):mark[row + i][col + j] = 1if table[row + i][col + j] == 0:f = 1breakelif col - 1 >= 0 and table[row + i][col - 1] == 1:f = 1breakelif col + clen <= cols - 1 and table[row + i][col + clen] == 1:f = 1breakelif row - 1 >= 0 and table[row - 1][j + col] == 1:f = 1breakelif row + rlen <= rows - 1 and table[row + rlen][j + col] == 1:f = 1breakif f == 1:ans_list.append('NO')else:ans_list.append('YES')cnt += 1
for ans in ans_list:print(ans)

C.Madoka and Childish Pranks

Problem

分析题目的操作可以发现,矩阵左上角的位置(1,1)是无法被染成黑色(1方格)的,如果目标矩阵的左上角为黑色则无解

考虑一种操作,对矩阵 (i,j)→(i+1,j)(i,j) \rightarrow (i+1,j)(i,j)→(i+1,j) 进行染色,即将 (i,j)(i,j)(i,j) 染为白色(0方格),将 (i+1,j)(i+1,j)(i+1,j) 染为黑色

opt1=[01]opt_1 = \begin{bmatrix} 0 \\ 1 \end{bmatrix} opt1​=[01​]

枚举每一列,从下向上遍历该列的方格。如果位置 (i,j)(i,j)(i,j) 应该染为黑色,则对 (i−1,j)→(i,j)(i-1,j) \rightarrow (i,j)(i−1,j)→(i,j) 进行染色,即可将该点变为黑色。使用这种操作,可以将除了第一行的所有方格进行正确的染色

对于第一行考虑另一种操作,对矩阵 (1,j)→(1,j+1)(1,j) \rightarrow (1,j+1)(1,j)→(1,j+1) 进行染色,即将 (1,j)(1,j)(1,j) 染为白色, (1,j+1)(1,j+1)(1,j+1) 染为黑色

opt2=[01]opt_2 = \begin{bmatrix} 0 & 1 \end{bmatrix} opt2​=[0​1​]

同理右向左遍历第一行的方格进行染色,即可将整个矩阵合法染色

在极限情况下,该方案需要进行 n∗mn * mn∗m 次染色,符合题目要求

cpp-version

int t,n,m;
char A[200][200];
int cnt;
struct hzq
{int x1,y1,x2,y2;hzq(int a=0,int b=0,int c=0,int d=0){x1=a,y1=b,x2=c,y2=d;}
}bb[20004];
inline void Main()
{cin>>t;while(t--){cin>>n>>m;rep(i,1,n)rep(j,1,m)cin>>A[i][j];if(A[1][1]=='1')cout<<"-1"<<endl;else{cnt=0;rep(j,1,m)per(i,n,2)if(A[i][j]=='1')bb[++cnt]=hzq(i-1,j,i,j);per(j,m,2)if(A[1][j]=='1')bb[++cnt]=hzq(1,j-1,1,j);cout<<cnt<<endl;rep(i,1,cnt){cout<<bb[i].x1<<sep<<bb[i].y1<<sep;cout<<bb[i].x2<<sep<<bb[i].y2<<endl;}}}return;
}

python3-version

n = int(input())cnt = 0while cnt < n:table = []tmp = input().split(' ')rows = int(tmp[0])cols = int(tmp[1])for row in range(rows):table.append([])num_str = str(input())for num in num_str:table[row].append(int(num))if table[0][0] == 1:print(-1)else:oper_list = []for col in range(cols):for row in range(1,rows):if table[rows-row][col] == 1:oper_list.append([rows-row, col + 1, rows-row + 1, col + 1])for col in range(1,cols):if table[0][cols-col] == 1:oper_list.append([1, cols-col, 1, cols-col + 1])print(len(oper_list))for i in oper_list:print(i[0], i[1], i[2], i[3])cnt += 1

D.Madoka and the Best School in Russia

Problem

对于good与beautiful的定义分析如下:

  • x是good的,则 x=k∗dx=k * dx=k∗d
  • x是beautiful的,则 x=k∗d,k≠0(modd)x=k * d, k \neq 0 \pmod{d}x=k∗d,k​=0(modd)

对于给定的x与d,题目要求寻找是否存在至少两种方案,将x分解为若干beautiful数

考虑将x分为 res∗di,res≠0(modd)res * d^i, res \neq 0 \pmod{d}res∗di,res​=0(modd) ,则一定存在下列方案:

res∗d,d,...,dres * d, d, ..., d res∗d,d,...,d

因此只需要判断是否存在第二种方案即可。这里使用简单的分类讨论。

虽然赛时遗忘了一种情况,哈哈

* 以下条件使用递进关系,即讨论i条件时,1~i-1条件均不满足

1.i=1

此时 x=res∗dx=res * dx=res∗d,因此只有x本身这一个方案

2.res=a * b

当res可以分解为两个不为1的整数时(即res不为1或者一个素数),可以得到第二种方案:

a∗d,b∗d,d,...,da * d, b * d, d, ..., d a∗d,b∗d,d,...,d

3.prime d

若res无法分解,且d为素数时,无法找到其他方案

*否则,可以考虑将d分解,以找到新的方案。下列情况对该情况进行讨论

4.i==2

可以发现在该情况下,无法将某一个d分解后得到新的有效解

5.i>3

此时考虑将一个d分解为 d1,d2d_1, d_2d1​,d2​,则第二种方案:

res∗d,d1∗d,d2∗d,...,dres * d, d_1 * d, d_2 * d, ..., d res∗d,d1​∗d,d2​∗d,...,d

6.i==3

最后一种情况: x=res∗d3,d=d1∗d2,prime:resx=res * d^3, d=d_1 * d_2, prime:resx=res∗d3,d=d1​∗d2​,prime:res

易知如果 res≠d1,d2res \neq d_1, d_2res​=d1​,d2​,则第二种方案:

res∗d1∗d,d2∗dres * d_1 * d, d_2 * d res∗d1​∗d,d2​∗d

只要能够找到d的一种分解方案,使得 res∗d1≠dres * d_1 \neq dres∗d1​​=d 即可

然而,如果 d=d1∗d2=res∗resd = d_1 * d_2 = res * resd=d1​∗d2​=res∗res ,则无法找到第二种方案,需要进行最后的判断

cpp-version

int t,x,d,res,cntd;
inline bool check(int x)
{if(x<=3)return true;for(int i=2;i*i<=x;++i){if(x%i==0)return false;}return true;
}
inline bool func()
{if(cntd<=1)return false;//cntd>=2if(check(res)==false)return true;//prime res,cntd>=2if(check(d)==true)return false;//non-prime d,prime res,cntd>=2if(cntd>3)return true;//non-prime d,prime res,cntd=2,3if(cntd==2)return false;//non-prime d,prime res,cntd=3if(res*res%d==0)return false;return true;
}
inline void Main()
{cin>>t;while(t--){cin>>x>>d;res=x,cntd=0;while(res%d==0){++cntd;res/=d;}if(func())cout<<"Yes"<<endl;else cout<<"No"<<endl;}return;
}

python3-version

t = int(input())
def check(x):if x <= 3:return Truei = 2while i * i <= x:if x % i == 0:return Falsei += 1return True
while t:t -= 1x, d = [int(i) for i in input().split(' ')]a, di = x, 0while a % d == 0:a, di = a // d, di + 1flag = Trueif di <= 1:flag = Falseelif check(a) == False:flag = Trueelif check(d) == True:flag = Falseelif di > 3:flag = Trueelif di == 2:flag = Falseelif a * a == d:flag = Falseif flag:print("Yes")else:print("No")

Codeforces Round #777 (Div. 2) 题解相关推荐

  1. Codeforces Round #777 (Div. 2) 简训

    Codeforces Round #777 (Div. 2) 简训 导语 涉及的知识点 题目 A Madoka and Math Dad B Madoka and the Elegant Gift C ...

  2. Codeforces Round #514 (Div. 2)题解

    Codeforces Round #514 (Div. 2)题解 A 喵,直接模拟. B 枚举所有盖章时的,合法的,左上角的位置.能盖的话就盖一下.最后check一下图案是否相等即可 C 一轮一轮的扔 ...

  3. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  4. 【算法题解】Codeforces Round #817 (Div. 4)题解

    文章目录 Codeforces Round #817 (Div. 4)题解 A. Spell Check B. Colourblindness C. Word Game D. Line E. Coun ...

  5. Codeforces Round #747 (Div. 2)题解

    Codeforces Round #747 (Div. 2)题解 (本博客将持续更新以后每场CF div2的题解,喜欢ACM.OI的小伙伴记得点个关注哟) 昨天夜晚刷网络流刷入迷了,渐渐就忘记了我还要 ...

  6. Codeforces Round #789 (Div. 2)题解

    Codeforces Round #789 (Div. 2)题解 A. Tokitsukaze and All Zero Sequence 原题链接 算法标签 贪心 排序 思路 情况一:数组存在零 → ...

  7. Codeforces Round #748 (Div. 3) 题解 完整A~G

    Codeforces Round #748 (Div. 3) 题解 A. Elections 题意 已知竞选中三个候选人的当前得票数 a , b , c a,b,c a,b,c,现在可以增加任何一个人 ...

  8. Codeforces Round #533 (Div. 2)题解

    link orz olinr AK Codeforces Round #533 (Div. 2) 中文水平和英文水平都太渣..翻译不准确见谅 T1.给定n<=1000个整数,你需要钦定一个值t, ...

  9. Codeforces Round #734 (Div. 3) 题解

    Hello大家好,今天给大家带来的是 Codeforces Round #734 (Div. 3) 的全题目讲解. 本文链接:https://www.lanqiao.cn/questions/2040 ...

最新文章

  1. linux中编译C语言程序
  2. 生物识别包含人脸识别门禁之外还包含哪种识别种类
  3. redis-cluster配置
  4. ShellSort 希尔排序
  5. Java I/O NIO学习
  6. (3)FPGA开发语言介绍(第1天)
  7. VC编程操作Word2010生成表格
  8. no module named ‘cv2’解决办法
  9. 9款很棒的网页绘制图表JavaScript框架脚本
  10. darknet框架_【杂谈】面向新手的深度学习开源框架指导手册与GitHub项目,欢迎加入我们的开源团队...
  11. 路由器PPPoE拨号密码(ADSL密码)找出方法 ZT
  12. 华中数控系统与高创驱动器EtherCat通讯设置及控制参数
  13. [Unity]使用状态机模式创建平台控制游戏(以Unity酱为例)
  14. 高通QCC5100系列蓝牙音频模块芯片
  15. bbs.ncar forum.php,无删减又好看的美剧资源网站
  16. HTML+CSS大风车及十字架的实现
  17. vue 生成 证书模板 并支持 图片下载和导出PDF的demo
  18. 如何记账能简单高效,记账全攻略来了
  19. Word批量设置图片大小
  20. echo命令的换行方法

热门文章

  1. 浅谈在线文档的那些事儿
  2. 数据库关系表 ---- Relational table
  3. 自旋锁 - 搬运自维基百科
  4. SSH隧道本地转发远程转发
  5. 谷歌是如何识别你真实的位置(location),然后封掉你的账号?
  6. 大学中的matlab课程,Matlab及在电子信息课程中的应用-中国大学mooc-题库零氪
  7. SpreadJS + GcExcel 一出,谁与争锋 全栈表格技术轻松应对复杂公式计算场景(一)
  8. C语言 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数
  9. X61 U盘安装系统
  10. 【Linux 内核】进程管理 - 进程优先级 ① ( 限期进程 | 实时进程 | 普通进程 | 进程优先级相关字段 )