A

思路:

一看到这个题,他不仅要求输出字典序最小的串,还要满足两两不重复,所以我们可以先输出ababab...什么的,最后缀上要求的k-2种字母

坑点:

  当然这样想是不完全的!该题是拥有许多特殊情况的!

  例:

    ①当n==k的时候(直接从字符‘a’往后面一个一个接着输出就好啦~)

    ②除去①之后若k==1(即只允许一中字符出现,但是又需要输出多个字符的情况)(直接输出-1)

    ③当k>n的时候(直接输出-1)

    ④当k==2的时候(能输出多少对ab就输出几对ab,若不成对的话,倒数第二个输出a,即abababababababa什么的)

    ⑤当k==3的时候(最后输出‘c’,前面能输出几对ab就输出几对ab,若不成对的话,倒数第二个输出a,即abababababababa什么的)

    ⑥其余为普通情况(见思路)

上代码:

#include <iostream>
#include <cstdio>
using namespace std; const int Maxn = ;
int n,k,cnt;
int p,p2;
//p是ab在不特殊情况下的总个数
//p2是在不特殊情况下除ab以外的总个数 int main()
{
freopen("str.in","r",stdin);
freopen("str.out","w",stdout);
scanf("%d%d",&n,&k);
if(n==k) {
for(int i=;i<n;++i)
printf("%c",(char)i+'a');
return ;
}
if(k== || k>n) {
printf("-1");
return ;
}
p=n-k+,p2=k-;
bool flag=false;
if(k<=) {
while(cnt<n) {
if(flag)
printf("b"),flag=false;
else
printf("a"),flag=true;
++cnt;
}
return ;
}
if(k==) {
while(cnt<n-) {
if(flag)
printf("b"),flag=false;
else
printf("a"),flag=true;
++cnt;
}
printf("c");
return ;
}
while(cnt<p) {
if(flag)
printf("b"),flag=false;
else
printf("a"),flag=true;
++cnt;
}
for(int i=;i<+p2;++i)
printf("%c",(char)i+);
return ;

B

思路:

  ①这是一道数论题,只需要根据排列组合推出来数学公式,然后用快速幂搞一搞即可(因为范围很大嘛~)

  ②在前k个点方案数的寻找中,也可以使用搜索

公式:

  ans=ksm(k,k-1)%Mod * ksm(n-k,n-k)%Mod;

坑点:

一、我怎么知道这个公式啊啊啊!!!

所以需要手动推导一下!!!

①ksm(k,k-1)

  • k==1的时候
  • 只有一种情况:1 —> 1
  • k==2的时候
  • 只有2种情况:1 —> 2 ,2 —> 1
  • k==3的时候
  • 情况稍微多一点: 我们这里用一个表格来进行演示!
  • 若还不懂,请自己手动实现一下吧还是。。。

②ksm(n-k,n-k)

  • 因为题目中提到除那k个点之外,其他点不能够连到1,而又因为k个点每个点都必须能够走到1,这即是说明后n-k个点不能够连到k个点,所以他们能够胡乱连,只要不到k个点即可,
  • 所以方案数为ksm(n-k,n-k);
  • (因为每个点都有n-k种选择)

③至于为什么要%Mod

  • 对此我只能说:题目要求。。。。

二、在搜索的时候数组一定不要开到8就算了,会T掉....

所以要开到9!!

看似数据中存在k==9的情况qwq ,因为我开到8后T了3个点,但是多加了一个之后就A了。。。

上代码:

  • 数论版:
#include <iostream>
#include <cstdio>
#define LL long long
using namespace std; const int Mod = 1e9 + ;
LL n,k,ans; inline LL read(LL &AC)
{
char ch=' ';LL x=,f=;
for(; (ch!='-') && ((ch<'')||(ch>'')); ch=getchar());
if(ch=='-') f=-,ch=getchar();
for(; ch>='' && ch<=''; ch=getchar()) x=x*+ch-;
AC=x*f; return AC;
} inline LL ksm(LL a,LL p) {
LL ret = ;
a%=Mod;
for(; p; p>>=, a=a*a%Mod)
if(p&)
ret=ret*a%Mod;
return ret;
} int main() {
read(n),read(k);
ans=ksm(k,k-)%Mod*ksm(n-k,n-k)%Mod;
printf("%lld",ans);
return ;
}
  • 搜索版:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long
using namespace std; const int Mod = 1e9 + ;
const int Maxk = ;
LL n,k,ans;
int pi[Maxk]; inline LL read(LL &AC)
{
char ch=' ';LL x=,f=;
for(; (ch!='-') && ((ch<'')||(ch>'')); ch=getchar());
if(ch=='-') f=-,ch=getchar();
for(; ch>='' && ch<=''; ch=getchar()) x=x*+ch-;
AC=x*f; return AC;
} inline LL ksm(LL a,LL p) {
LL ret = ;
a%=Mod;
for(; p; p>>=, a=a*a%Mod)
if(p&)
ret=ret*a%Mod;
return ret;
} inline bool check() {
bool vis[Maxk];
memset(vis,false,sizeof(vis));
int now=;
while(!vis[now]) {
vis[now]=true;
now=pi[now];
}
///从 1 出发必须能够回到 1
if(now!=)
return false;
for(int i=; i<=k; ++i) {
if(!vis[i]) {
bool vis2[Maxk];
memset(vis2,false,sizeof(vis2));
int now2=i;
while(!vis2[now2] && !vis[now2]) {
vis2[now2]=true;
now2=pi[now2];
}
if(!vis[now2])
return false;
}
}
return true;
} void dfs(int now) {
if(now==k+) {
if(check())
ans++;
return ;
}
for(int i=; i<=k; ++i) {
pi[now]=i;
dfs(now+);
}
} int main() {
read(n),read(k);
dfs();
ans=ans*ksm(n-k,n-k)%Mod;
printf("%lld",ans);
return ;
}

C

思路:

这题需要优化的dp!!!

  但是为什么可以优化那?

  首先时间上的优化:

    因为每一次递推改变的是一个范围内的值,所以能用差值维护。

  其次空间上的优化:

    每一步仅与他的上一步有关,能用滚动数组。

坑点:

最后ans记录的时候用的是last,不是now,因为最后有一次互换操作!

上代码:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#define LL long long
using namespace std; const int Maxn = ;
const int Mod = 1e9 + ;
int n,a,b,k;
///滚动数组 ,二维是代表终点在第几层
LL dp[][Maxn];
///up代表第i层能走到的最上方的层数为...,down反之
int up[Maxn],down[Maxn]; int main() {
freopen("lift.in","r",stdin);
freopen("lift.out","w",stdout);
scanf("%d%d%d%d",&n,&a,&b,&k);
int last=,now=;
///初始化:自己从a出发到a的方法只有1种
dp[last][a]=;
for(int i=; i<=n; ++i) {
///处理每一层到达b的距离
int dis=abs(i-b);
/*
1-n是从上到下,所以i-dis+1要比i+dis-1要小,所以i-dis+1在上方
见图示
又因为i可能减不了,但是up又不能够<1,所以在i-dis+1跟1中取max
down同理
*/
up[i]=max(,i-dis+);
down[i]=min(n,i+dis-);
}
for(int i=; i<=k; ++i) {
///使用滚动数组要先将将要更新的清零
for(int j=; j<=n; ++j)
dp[now][j]=;
for(int j=; j<=n; ++j) {
(dp[now][up[j]]+=dp[last][j])%Mod;
(dp[now][down[j]+]-=dp[last][j])%Mod;
}
///处理前缀和
for(int j=; j<=n; ++j)
(dp[now][j]+=dp[now][j-])%Mod;
///滚动数组(处理完前缀和之后,上一个就已经没用了,减去)
for(int j=; j<=n; ++j)
(dp[now][j]-=dp[last][j])%Mod;
///进行交换
swap(last,now);
}
int ans=;
/*
为什么用last不用now呢?
因为上一个for循环中最后结束的时候又把last跟now换了
所以本来最后i==k时now代表k,换完之后变为last
*/
///因为每一层都有可能是终点,ans都累加一遍即可
for(int i=; i<=n; ++i)
(ans+=dp[last][i])%Mod;
///防止出现负数
ans=(ans+Mod)%Mod;
cout<<ans;
return ;
}

日照学习提高班day4测试的更多相关文章

  1. 日照学习提高班day3测试

    A 思路: 一看到'#''.'什么的就想到搜索怪我怪我... 这道题勉强说是搜索别打我qwq 1)因为不重复,所以首先要判断是否%5==0,若不满足,直接输出NO 2)弄个vis数组记录是否被搜过,如 ...

  2. 夏令营提高班上午上机测试 Day 2 解题报告

    那一天,日照一中夏令营数据结构提高班的同学们终于想起了,被Day2上午的三道题支配的恐惧……   是的..这一天的题有点难想.. 本来打算前天写这篇随笔,然而前天在机房和同学打luogu月赛…… 昨天 ...

  3. 今天,Java编程周末提高班(第一期)正式结束

    Java编程周末提高班(第一期),走过了近两个月历程,一共同拥有68人次学生周末到老师家进行Java学习与交流.近距离的和一群年轻的学习接触,收获非常多,特别是对以后教学的改进.在学习的闲暇.大家自己 ...

  4. 《从零开始学Swift》学习笔记(Day4)——用Playground工具编写Swift

    Swift 2.0学习笔记(Day4)——用Playground工具编写Swift 原创文章,欢迎转载.转载请注明:关东升的博客 用Playground编写Swift代码目的是为了学习.测试算法.验证 ...

  5. 老段带你学鸟哥Linux视频教程 包含基础班+提高班

    老段带你学鸟哥Linux视频教程 包含基础班+提高班,附带pdf文档. 目录结构如下: 目录:/-老段带你学鸟哥Linux视频教程 [.9G] ┣━━老段带你学鸟哥-服务器篇 [1009.4M] ┃ ...

  6. 学习版pytest内核测试平台开发万字长文入门篇

    前言 2021年,测试平台如雨后春笋般冒了出来,我就是其中一员,写了一款pytest内核测试平台,在公司落地.分享出来后,有同学觉得挺不错,希望能开源,本着"公司代码不要传到网上去,以免引起 ...

  7. 夏令营提高班上午上机测试 Day 3 解题报告

    今天的题的确水.T3还是一道NOIP原题. 嘛,多刷点水题也不是什么坏事嘛. 说来也快,夏令营结束了整一星期了呢.大家也都回到了日常的暑假生活呢. 今天学业水平测试出成绩了...嗯结果还算满意呢,至少 ...

  8. 夏令营提高班上午上机测试 Day 4 解题报告

    我要是没记错的话,今天的题难度算挺适中的. *标程来自高天宇哥哥 T1:小G的字符串 题目描述 有一天,小 L 给小 G 出了这样一道题:生成一个长度为 n 的.全由小写英文字母构成的字符串,只能使用 ...

  9. 夏令营提高班上午上机测试 Day 1 解题报告

    Day 1的题难度上来说不算太高,但是T2和T3还是有一定的思维量的. 一个比较好的开始.虽然AK的人只有几个.. (懒得去翻result了..忘了当时拿了多少分了 (哦,前两天我们机房是没有成绩的, ...

随机推荐

  1. 缓存策略:redis缓存之springCache

    最近通过同学,突然知道服务器的缓存有很多猫腻,这里通过网上查询其他人的资料,进行记录: 缓存策略 比较简单的缓存策略: 1.失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放 ...

  2. 进阶Java编程(11)ClassLoader类加载器【待完成】

    1,ClassLoader类加载器简介 在Java里面提供一个系统的环境变量:ClassPath,这个属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指 ...

  3. 汉明码(hamming code)

    hamming code用于磁盘RAID 2中, 关于汉明码的讲解可以看这篇博文,介绍的很详细.最重要是最后的结论: 汉明码属于分组奇偶校验,P4P2P1=000,说明接收方生成的校验位和收到的校验位 ...

  4. vue 节流

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. shell运行下的写日志

    tee 重定向输出到多个文件   在执行Linux命令时,我们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可以使用tee命令 要注意的是:在使用管道线时,前一个命令的标准错误输出不会被tee读 ...

  6. 附件上传vue组件封装(一)

    //父页面部分 <attachment @newFileList="newFileList" :operationType="operationType" ...

  7. Oracle笔记(九) 表的创建及管理

    对于数据库而言实际上每一张表都表示的是一个数据库的对象,而数据库对象指的就是DDL定义的所有操作,例如:表.视图.索引.序列.约束等等,都属于对象的操作,所以表的建立就是对象的建立,而对象的操作主要分 ...

  8. 20、linux启动流程和救援模式

    1.Linux启动流程 2.Linux运行级别 1.什么是运行级别,运行级别就是操作系统当前正在运行的功能级别 System V init运行级别 systemd目标名称 作用 0 runlevel0 ...

  9. 第七章·Logstash深入-收集NGINX日志

    1.NGINX安装配置 源码安装nginx 因为资源问题,我们先将nginx安装在Logstash所在机器 #安装nginx依赖包 [root@elkstack03 ~]# yum install - ...

  10. Vivotek 摄像头远程栈溢出漏洞分析及利用

    Vivotek 摄像头远程栈溢出漏洞分析及利用 近日,Vivotek 旗下多款摄像头被曝出远程未授权栈溢出漏洞,攻击者发送特定数据可导致摄像头进程崩溃. 漏洞作者@bashis 放出了可造成摄像头 C ...