2021.7.20C组总结

题目依然水,本蒻依然挂

基本功还是不够扎实。。。

T1 排座椅

题目描述

上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳。同学们在教室中坐成了M行N列,坐在第i行第j列的同学的位置是(i,j),为了方便同学们进出,在教室中设置了K条横向的通道,L条纵向的通道。于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通道的位置,因为如果一条通道隔开了两个会交头接耳的同学,那么他们就不会交头接耳了。
请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生对数最少。

输入

输出

​ 输出文件seat.out共两行。
​ 第一行包含K个整数,a1a2……aK,表示第a1行和a1+1行之间、第a2行和第a2+1行之间、…、第aK行和第aK+1行之间要开辟通道,其中ai< ai+1,每两个整数之间用空格隔开(行尾没有空格)。
​ 第二行包含L个整数,b1b2……bk,表示第b1列和b1+1列之间、第b2列和第b2+1列之间、…、第bL列和第bL+1列之间要开辟通道,其中bi< bi+1,每两个整数之间用空格隔开(行尾没有空格)。

样例输入

4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4

样例输出

2
2 4

个人理解:

解决这个问题有什么用呢,难道不知道还有纸条这种东西吗

这道题我感觉是最简单的唯一一道比赛AC的题目,用贪心思想

用个h数组存 i行与i+1行之间若建一条过道可隔开交头接耳的对(这里是量词)数,列也如此

而存数组的数的过程在输入时进行,若两个X坐标相同,l[min(y1,y2)]++,反过来也一样

然后l和h分别枚举,每次找maxn,找到后bool数组pl与ph标记为一,原l与h被选中的数改为0

最后输出pl与ph中为一的i
code:

#include<cstdio>
#include<cstring>
int M,N,K,L,D,x1,y1,x2,y2,ansk[100001],ansl[100001],maxn,mx,ans1[100001],ans2[100001];
int min(int xd,int yd){return xd<yd?xd:yd;
}
int main(){scanf("%d%d%d%d%d",&M,&N,&K,&L,&D);for(int i=1;i<=D;i++){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);if(x1==x2){ansl[min(y1,y2)]++;}if(y1==y2){ansk[min(x1,x2)]++;}}while(K!=0){maxn=0;mx=0;for(int i=1;i<=M;i++){if(maxn<ansk[i]){mx=i;maxn=ansk[i];}}if(mx!=0){ans1[mx]=1;ansk[mx]=0;}K--;}while(L!=0){maxn=0;mx=0;for(int i=1;i<=N;i++){if(maxn<ansl[i]){mx=i;maxn=ansl[i];}}if(mx!=0){ans2[mx]=1;ansl[mx]=0;}L--;}for(int i=1;i<=M;i++){if(ans1[i]==1)printf("%d ",i);}printf("\n");for(int i=1;i<=N;i++){if(ans2[i]==1)printf("%d ",i);}return 0;
}

T2传球游戏

题目描述

​ 上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。
​ 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没传出去的那个同学就是败者,要给大家表演一个节目。
​ 聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里。两种传球的方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有3个同学1号、2号、3号,并假设小蛮为1号,球传了3次回到小蛮手里的方式有1->2->3->1和1->3->2->1,共2种。

输入

​ 输入文件ball.in共一行,有两个用空格隔开的整数n,m(3<=n<=30,1<=m<=30)。

输出

​ 输出文件ball.out共一行,有一个整数,表示符合题意的方法数。

样例输入

3 3

样例输出

2

个人理解:

嗯,这题,实际上就是DP双“前缀和”

来个dp数组

dp[i] [j]表示的是第 i 次传球,传给第 j 个人的方案数和

因为每个人可以往他的两边传,反过来也就是他的两边可以给他传

所以第 i 次传给方案数就是i-1次,传给他左右的方案数的和

由此我们可以得出这道题的状态方程转移式:

dp[i] [j]=dp[i-1] [j-1] + dp[i-1] [j+1]

但注意,由于大家是坐成一个圈的,所以dp[i] [0]=dp[i] [n],dp[i] [n+1]=dp[i] [1]

然后注意初始值设个dp[0] [1]=1即可(枚举1~m)

code:

#include<cstdio>
#include<cstring>
int n,m,f[1001][1001];
int main(){scanf("%d%d",&n,&m);f[0][1]=1;for(int i=1;i<=m;i++){f[i-1][0]=f[i-1][n];f[i-1][n+1]=f[i-1][1];for(int j=1;j<=n;j++){f[i][j]=f[i-1][j-1]+f[i-1][j+1];}}printf("%d",f[m][1]);return 0;
}

T3 立体图

题目描述

​ 小渊是个聪明的孩子,他经常会给周围的小朋友们讲些自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。
​ 小渊有一块面积为mn的矩形区域,上面有mn个边长为1的格子,每个格子上堆了一些同样大小的吉姆(积木的长宽高都是1),小渊想请你打印出这些格子的立体图。我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放:

..+---+
./   /|
+---+ |
|   | +
|   |/.
+---+..

​ 每个顶点用1个加号’+’表示,长用3个”-“表示,宽用1个”/”表示,高用两个”|”表示。字符’+’ ‘-‘’/’ ‘|’的ASCII码分别为43,45,47,124。字符’.’(ASCII码46)需要作为背景输出,即立体图里的空白部分需要用’.’代替。立体图的画法如下面的规则:
​ 若两块积木左右相邻,图示为:

..+---+---+
./   /   /|
+---+---+ |
|   |   | +
|   |   |/.
+---+---+..

若两块积木上下相邻,图示为:

..+---+
./   /|
+---+ |
|   | +
|   |/|
+---+ |
|   | +
|   |/.
+---+..

若两块积木前后相邻,图示为:

....+---+
.../   /|
..+---+ |
./   /| +
+---+ |/.
|   | +..
|   |/...
+---+....

立体图中,定义位于第(m,1)的格子(即第m行第1列的格子)上面自底向上的第一块积木(即最下面的一块积木)的左下角顶点为整张图最左下角的点。

输入

​ 输入文件drawing.in第一行有用空格隔开的两个整数m和n,表示有mn个格子(1<=m,n<=50)。
​ 接下来的m行,是一个m
n的矩阵,每行有n个用空格隔开的整数,其中第i行第j列上的整数表示第i行第j列的格子上摞有多少个积木(1<=每个格子上的积木数<=100)。

输出

​ 输出文件drawing.out中包含题目要求的立体图,是一个K行L列的字符矩阵,其中K和L表示最少需要K行L列才能按规定输出立体图。

个人理解:

就不搞什么样例了,有很多原因主要是懒

这题不用太多算法与思考,但实现起来很难

我看到这题时有些无从下手,在于如何找到立方体的位置

现实中当你看一些立方体时,会有一些面被遮住,而这些被遮住的,在这道题中,到后面是会被后面打印的覆盖的

我们来一张char类型的map[] []数组当做输出,背景为‘.’

然后再来一个char类型数组存正方形的每一行

接下来就是算这张map的长和宽了

长很好算,由于每个立方体‘±–+’占4,n个就是n * 4 + 1(多出来一个‘+’),以及‘+/+’占了2(左边的‘+’重复了),所以n个立方体就占n * 4 + 1 +n*2

而宽就要在输入时,宽=max(宽,(n - i + 1) * 2 + a[i] [j] * 3 + 1)

解释:a[i] [j]指第 i 行,第 j 列的高度(也就是有几个立方体),有x个立方体,就占3 * x + 1

(‘+

​ |

​ |

​ +’)

接下来,就是确定立方体的画法了:

我们为了让后画的能覆盖住前面画的,而不是反过来,那么画的顺序就是:

从最左最后最下的立方体开始画,先从下往上,再从左往右,再从前往后

而每个立方体是从下往上一行一行在map上赋值

知道了顺序,就来确定位置了:

行呢,因为已经知道map的长了,通过观察可以发现,前面有x个立方体,就会有x个‘+/’,也就是会占2 * x行,因此我们用map的长减一下(长 - 2 * x),但行还会随k(1~a[i] [j])向上变,所以没打印完一个立方体,行就要往上移3,同时它也随着打印立方体而一行一行往上(因为是从下往上一行一行)

好了,到列了,与上面相同,前面有x个立方体就有x个’x/‘,同时,左边有y个立方体,就又占4* y(’±–‘),但由于它还会再打印时一个一个向右移,我们设正在打印第 z 个,还因为立方体的第一行比其它往右2,第二行,往右1,所以列就是2 * x + 4 * y + z(+2或+1)

最后输出即可

code:

#include<cstdio>
#include<cstring>
int n,m,a[201][201],h,maxn,lie,len[7]={0,5,6,7,7,6,5};
char ans[201][201],zfx[11][11]={{},{'\0','+','-','-','-','+'},{'\0','/',' ',' ',' ','/','|'},{'\0','+','-','-','-','+',' ','|'},{'\0','|',' ',' ',' ','|',' ','+'},{'\0','|',' ',' ',' ','|','/'},{'\0','+','-','-','-','+'}};
int max(int x,int y){return x>y?x:y;}
int main(){scanf("%d%d",&n,&m);lie=m*4+1+n*2;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);h=max(h,(n-i+1)*2+a[i][j]*3+1);}}for(int i=1;i<=h;i++){for(int j=1;j<=lie;j++){ans[i][j]='.';}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){for(int k=1;k<=a[i][j];k++){for(int l=6;l>=1;l--){int gannm=(n-i)*2+(j-1)*4;if(l==1){gannm+=2;}if(l==2){gannm++;}for(int l2=1;l2<=len[l];l2++){ans[h-(n-i)*2-6+l-(k-1)*3][gannm+l2]=zfx[l][l2];}}}}}for(int i=1;i<=h;i++){for(int j=1;j<=lie;j++){printf("%c",ans[i][j]);}printf("\n");}return 0;
}

T4 间谍派遣

题目描述

你是M,一个雇佣N个标号为从1到N的间谍的情报机关的总管。每个间谍被派往不同的国家并在那获取重要情报。

如下是你的任务:

1.在部分间谍间组织会面。每次会面在两个间谍间进行,两个间谍交换他们自己获取的或从之前会面中得到的信息。因为在不同国家的两个间谍间组织机密会面很困难,所以每次秘密会面都有一个费用。

2.当所有会面结束后,选择一部分间谍参加拯救世界的任务。一个间谍k参加此项任务需要花费Mk。很重要的一点是,任务要成功,必须满足参加任务的间谍获取的情报聚集到一起包含了其他剩余间谍所有的信息。

请找出完成任务的最小花费,即组织会面和派遣间谍的费用之和。

输入

输入的第一行包含正整数N,表示间谍数目(2≤N≤1000)。

接下来的N行包含N个不超过10^6的非负整数。在k行m列的数字表示间谍k和m间会面的花费,同样的,与m行k列的数字相等,k=m时数字为0。

接下来的一行包含N个正整数Mk(1≤Mk≤10^6),分别为派遣间谍1,2,…,N参加任务的花费。

输出

只有一行,为所需的最小总费用。

样例输入

输入1:30 6 96 0 49 4 07 7 7输入2:30 17 2017 0 1020 10 015 9 12输入3:50 3 12 15 113 0 14 3 2012 14 0 11 715 3 11 0 1511 20 7 15 05 10 10 10 10

样例输出

输出1:17输出2:34输出3:28

个人理解

比赛时,我竟然想找规律!

实际上,这题是最小生成树。。。

我们把去拯救世界的费用,看成去和第n+1个人会和的费用

那么就建造出一幅最小生成树的双向图

本蒻仅知可用prim和kruskal(若有其他方法请告诉本蒻)

接下来讲讲如何用kruskal算法(并查集)做本题:

首先来三个数组x,y,z分别存两人与会和费用

然后qsort一下,把它们从小到大排一遍

再枚举一下,判断一下在不在同个集合,若不在,就合并一下,在,就跳过

每次合并,sum+=费用

最后输出sum即可

code:

#include<cstdio>
#include<cstring>
long n,a,b,sum=0,x[100001],y[100001],z[100001],num=0,f[100001];
long find(long x1){if(x1!=f[x1]){f[x1]=find(f[x1]);}return f[x1];
}
void uni(long x1,long y1){x1=find(x1);y1=find(y1);f[y1]=x1;return ;
}
bool jud(long x1,long y1){x1=find(x1);y1=find(y1);if(x1==y1){return true;}return false;
}
void swap(long &hz,long &hh){long t=hz;hz=hh;hh=t;return ;
}
void pl(long i,long j){long l=i,r=j,mid=z[(i+j+1)/2];while(i<=j){while(z[i]<mid)i++;while(z[j]>mid)j--;if(i<=j){swap(z[i],z[j]);swap(x[i],x[j]);swap(y[i],y[j]);i++;j--;}}if(l<j)pl(l,j);if(i<r)pl(i,r);return ;
}
int main(){scanf("%ld",&n);for(long i=1;i<=n;i++){for(long j=1;j<=n;j++){scanf("%ld",&a);if(j>i){x[++num]=i;y[num]=j;z[num]=a;}}f[i]=i;}for(long i=1;i<=n;i++){scanf("%ld",&b);x[++num]=i;y[num]=n+1;z[num]=b;}pl(1,num);for(int i=1;i<=num;i++){if(jud(x[i],y[i])!=1){uni(x[i],y[i]);sum=sum+z[i];} } printf("%ld",sum);return 0;
}

T5 seek

题目描述

俗话说“好命不如好名”,小h准备给他的宠物狗起个新的名字,于是他把一些英文的名字全抄下来了,写成一行长长的字符串,小h觉得一个名字如果是好名字,那么这个名字在这个串中既是前缀,又是后缀,即是这个名字从前面开始可以匹配,从后面开始也可以匹配,例如abc在 abcddabc中既是前缀,也是后缀,而ab就不是,可是长达4*10^5的字符让小h几乎昏过去了,为了给自己的小狗起个好名字,小h向你求救,并且他要求要将所有的好名字的长度都输出来。

输入

一行,要处理的字符串(都是小写字母)。

输出

一行若干个数字,从小到大输出,表示好名字的长度。

样例输入

abcddabc

样例输出

3 8

个人理解

本题就是找公共前后缀,用KMP算法即可

前缀与后缀完全相同

在前缀1里找的公共前后缀2的后缀2在后缀1也能找到,并且也是后缀1的后缀

因此我们只要在上个找出的最长公共前后缀里再找出新的最长公共前后缀

首先建立next数组,原串和对比串都是p[ ]

然后while(当前next[ ]不为零)

这么找下去,边找边用ans数组记录

然后输出

code:

#include<cstdio>
#include<cstring>
const int N=5e9;
int net[500000000],len,pi,si,x=1,now,ans[500000000],k,t;
char p[500000000];
void BN(){while(x<len){if(p[x]==p[now]){now++;net[x]=now;x++;}else if(now>0){now=net[now-1];}else{net[x]=0;x++;    }}return ;
}
int main(){scanf("%s",p);len=strlen(p);BN();k=len-1;ans[++t]=len;while(net[k]){ans[++t]=net[k];k=net[k]-1;}for(int i=t;i>=1;i--){printf("%d ",ans[i]);}return 0;
}

总结

基本功还是不够扎实,虽然知道T5是KMP,但却无从下手。。

多想想,不轻易放弃才行。。

END

2021.7.20C组总结(详细!!)相关推荐

  1. 2021中职组网络空间安全国赛CD模块分组混战镜像*

    2021中职组网络空间安全国赛CD模块分组混战镜像 新规程的C,D模块环境 有想法的私信

  2. 北航2021届计组 - 支持中断的CPU

    北航2021级计组支持中断的CPU Itisallaboutcontrol,cheatandtradeoff.It\space\space is\space\space all\space\space ...

  3. 2021年重庆各中学高考成绩查询,2021年重庆市重点高中详细排名

    2021年重庆市重点高中详细排名2021-04-06 15:12:26文/勾子木 2021年重庆市重点高中排名是怎样的呢?下面总结了2021年重庆市高中排名,仅供参考. 2021年重庆市重点高中排名 ...

  4. 北航2021届计组 -- 流水线CPU

    北航2021届计组流水线CPU设计 文章目录 北航2021届计组流水线CPU设计 一.设计想法 1.1 我的CPU的整体架构 1.2 从单周期到流水线 1.2.1 修改原单周期CPU 1.2.2 流水 ...

  5. Linux修改文件所属用户及所属组(详细)

    Linux修改文件所属用户及所属组(详细) chgrp 修改文件所属组 chown 修改文件所属用户及所属组 chgrp 修改文件所属组 chgrp用于修改文件所属组. 基本语法 chgrp [-R] ...

  6. 2021最新IDEA初级入门详细教程流出,开发组小伙伴怒赞

    本次安装的 IntelliJ IDEA 版本:2020.2 (当前最新版本,2020.07.28发布的202.6397.94版) 官方推荐的安装条件(指当前你手里电脑的配置)如下: 1.64位版本的 ...

  7. 2021年超全超详细的最新大数据开发面试题,附答案解析

    版本 时间 描述 V1.0 2020-12-18 创建 V1.2 2021-01-17 新增 spark 面试题 V1.3 2021-01-18 新增 kafka 面试题 V1.4 2021-01-2 ...

  8. Bank相关11_8583报文手动组包——详细分析每个示范域

    8583报文作为一种应用较广的报文,有它独特的格式. 网上有关8583报文的说明很多.但涉及到每个域的详细例子就较少了.这里列出各个域的详细例子,供参考. 8583报文: 报文组成: 报文头[长度(2 ...

  9. 2022IntelliJ IDEA 创建Servlet最最最新方法IDEA版本2021.2.2(超详细)附加tomcat到idea中。

    2022在初学jiave web 的过程中创建servlet出现了一些问题,在网上也没找到太详细的方法,不过最终还是解决了该问题,为了让其他同学不会在此花费太长时间,我决定自己写一个较为详细的步骤.以 ...

最新文章

  1. Qt中文手册 之 QTableWidgetItem
  2. Vue底层实现原理概述
  3. linux文件夹多个空格,linux-在“ for”循环中读取带有空格,带有多个输入文件的制表符的完整行...
  4. 启明云端分享|AIOT+智慧屏解决方案,用色彩渲染智慧生活
  5. DNS攻击的主要方式
  6. vue项目中按需引入viewUI
  7. 拆分-洛谷P2745 [USACO5.3]窗体面积Window Area
  8. 不值钱的软件人才[转]
  9. Spring Boot笔记-jQuery使用load进行异步调用
  10. gsp 页面 html.dat,grails2.3.x在gsp显示html
  11. 百度地图 截图java_[Java教程]百度地图API 简单使用
  12. [Serializable]的应用--注册码的生成,加密和验证
  13. python的objectproperty,python – ObjectProperty类的用法
  14. 前后端分离的思考与实践(四)
  15. 单片机中断交通灯c语言程序设计,基于c语言单片机交通灯
  16. linux运维故障案列,linux 运维故障排查思路
  17. 【经验分享】PC端免费高效的同声翻译
  18. verilog逻辑符
  19. 大数据系统和分析技术综述【程学旗】
  20. 解决Server2008下远程桌面连接“由于没有终端服务器许可证服务器可以提供许可证”

热门文章

  1. 数据统计分析(3):数据的集中趋势描述
  2. GROMACS的安装以及部分常见报错
  3. 51物联卡:物联网卡使用中能更换流量套餐吗?
  4. 数创空间&国际华语音乐联盟达成合作,将联合发行系列数字音乐藏品
  5. 使用devstack安装部署OpenStack(据详细手把手教学)
  6. ps流组成 PS封装 (PS+SYS+PSM+PES+RAW )概述
  7. python实现SMB服务账号密码爆破功能 Metasploit 中的 smb_login
  8. 无线化超轻薄,香港城市大学体感反馈贴片WeTac
  9. 教你一分钟看懂建筑图纸,包学包会!
  10. 如何去设计体验感超强的线上训练营?