我要是没记错的话,今天的题难度算挺适中的。
*标程来自高天宇哥哥
T1:小G的字符串

题目描述

有一天,小 L 给小 G 出了这样一道题:生成一个长度为 n 的、全由小写英文字母构成的字符串,只能使用 k 种字母。要求满足:

  • 字符串中相邻的两个字母不能相同。
  • 必须出现恰好 k 种不同的字母。

这样的合法字符串可能有很多,小 L 让小 G 输出字典序最小的那个。

小 G 太笨啦,不会做这道题,希望你帮帮他。

输入格式

输入文件只有两个数字 n; k,含义如题。

输出格式

输出文件共一行,输出合法的字典序最小的字符串。

如果不存在任意一个合法的方案,输出 1。

样例输入

7 4

样例输出

ababacd

数据范围

对于 100% 的数据,1≤n≤105; 1≤k≤26

 
题目大概的意思是说让我们生成一个字典序最小的字符串,满足相邻字符不相同,并且出现k个不同的字符。
乍一看无法下手,其实特别特别简单。。
(表面慌的一匹,实则稳如老狗)
对于k>2的情况,只需要在前面不断输出ababab……最后把剩下的字符都输出出来就好了。
这样显然是字典序。
恶心的是,特殊情况太多。
k>n,直接-1不用考虑
k=1,n=1,只输出一个a
k=1,n>1这个显然-1
k=2,全都是abababab…
 
 #include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std; int main() {
freopen("str.in", "r", stdin);
freopen("str.out", "w", stdout);
int n, k;
cin >> n >> k; if (k > n) {
cout << - << endl;
return ;
} if (k == ) {
if (n > )
cout << - << endl;
else
cout << "a" << endl;
} else if (k == ) {
for (int i = ; i <= n; i++)
if (i % ) putchar('a');
else putchar('b');
putchar('\n');
} else {
for (int i = ; i <= n - (k - ); i++)
if (i % ) putchar('a');
else putchar('b');
for (int i = ; i < k; i++) putchar('a' + i);
putchar('\n');
}
}
 
T2:小G的城堡

题目描述

小 G 家有一座城堡。城堡里面有 n 个房间,每个房间上都写着一个数字 pi

小 G 拉着几个小伙伴在城堡里面玩耍,他们约定,如果某个人当前站在 i 房间里面,下一步这个人就会去 pi 房间,再下一步这个人去 ppi 

为了增加趣味性,小 G 想重新书写每个房间的 pi,以满足:

  • 如果从编号 1 到 k 中的某个房间开始,按照规则走,必须能够走到 1 号房间。特别地,如果从 1 号房间开始走,也要能够走回 1 号房间(至少走一步,如果 p1 = 1,从 1 走到 1 也算合法)。
  • 如果从编号大于 k 的某个房间开始,按照规则走,一定不能走到 1 号房间。

小 G 想知道,有多少种书写 pi 的方案,可以满足要求。

输入格式

输入文件一行两个数字 n; k,含义如题。

输出格式

输出文件一个数字,表示合法的方案数。答案对 10+ 7 取模

样例输入 1

5 2

样例输出 1

54

样例输入 2

7 4

样例输出 2

1728

数据范围

对于 40% 的数据,1 ≤ n ≤ 8

对于 70% 的数据,1 ≤ n ≤ 105

对于 100% 的数据,1 ≤ n ≤ 1018; 1  ≤k ≤min(8,n)。

 
题目大意:有n个点,每个点有一条出边。要求前k个点能走到1号点,后k个点不能走到一号点,问方案数。
n<=8
暴力搜索,看每个点的出边指向哪里,然后检查就好。
n<=10^5
我们发现,前k个点肯定和前k个点互相连边。后n-k个点肯定不会连到前k个点里面去。
所以,我们只要爆搜前k个点连接的方案,然后检查;后n-k个点,只要连的是后n-k个点,爱怎么连怎么连,方案数是(n-k)^(n-k)。最后把两部分方案数乘起来就行。
n<=10^18
(n-k)^(n-k)太大?请使用快速幂。
  

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
using namespace std; typedef long long ll;
const int mod = 1e9 + ; ll n, k;
ll ans = ; inline ll qe(ll a, ll p) {
ll ans = ;
a %= mod;
for (; p; p >>= , a = a * a % mod)
if (p & )
ans = ans * a % mod;
return ans;
} int go_loc[]; inline bool check() {
static bool vis[];
memset(vis, , sizeof(vis)); int now = ;
while (!vis[now]) {
vis[now] = true;
now = go_loc[now];
}
if (now != ) return false;
for (int i = ; i <= k; i++)
if (!vis[i]) {
static bool other_vis[];
memset(other_vis, , sizeof(other_vis));
int now = i;
while (!other_vis[now] && !vis[now]) {
other_vis[now] = true;
now = go_loc[now];
}
if (!vis[now]) return false;
}
return true;
} void dfs(int now) {
if (now == k + ) {
if (check()) ans++;
return;
}
for (int i = ; i <= k; i++) {
go_loc[now] = i;
dfs(now + );
}
} int main() {
freopen("castle.in", "r", stdin);
freopen("castle.out", "w", stdout);
cin >> n >> k;
dfs();
ans = ans * qe(n - k, n - k) % mod;
cout << ans << endl;
}
 
T3:小G坐电梯

题目描述

小 G 来到了著名的 CIGOM 大厦。大厦一共有 n 层,初始的时候小 G 在第 A 层。小 G 特别想去 B 层小 M 的办公室看一看,然而因为安保原因,B 层已经被封锁无法进入。

但是小 G 既然来了,就想在大厦里面逛一逛。大厦里面有一部电梯,小 G 决定坐 k 次电梯。因为小 G 比较无聊,他给自己设定了这样一个规矩:假如当前他在 x 层,则他要去的下一个楼层 y  x 的楼层差必须要小于 x  B 的楼层差,即|x-y| < |x-B|。每到达一个楼层,小 G 都要记录下来其楼层号。

当小 G 转完一圈后,他也记录下了 k + 1 个楼层号(可能有重复)。小 G 现在想知道,按照他定下的规矩,一共有多少种可能的楼层号序列?

输入格式

输入文件一行,4 个数字 n,A, B, k,含义如题目所述。

输出格式

输出一个数字,表示可能的楼层号序列的数量。答案对 109 + 7 取模。

样例输入 1

5 2 4 1

样例输出 1

2

样例输入 2

5 2 4 2

样例输出 2

2

样例输入 3

5 3 4 1

样例输出 3

0

数据范围

对于 30% 的数据,2≤ n≤ 8; 1 ≤ k ≤ 8。

对于 70% 的数据,2 ≤ n 300; 1 ≤ k ≤ 300。

对于 100% 的数据,2 ≤ n ≤ 5000; 1 ≤k ≤5000; 1≤ A,B≤n; A ≠B

这个题告诉我们,有n个楼层,走k步。每次走的距离不能超过当前点距离B层的距离。问方案数。
搜索是显然的,但这个题正解是DP。
注意到主人公永远不能跨越B层。
令f[step][i]表示当前是第step步,走到i这个位置的方案数。
转移(我们以B层下侧为例):
f[step][i]=f[step-1][1~i-1]+f[step-1][i+1~ k]
其中,如果i+B为偶数,k=(i+B)/2-1
i+B为奇数,k=(i+B)/2
但这样并不能过所有点,因为转移是O(n)的。
我们要用O(1)的转移。注意我们每次的转移都来自一个连续的区间,而且我们是求和
来自一个连续的区间,还要求和,读者朋友,您是不是想到了前缀和?
令sum[step][i]表示f[step][1~i]的和
还是以B下侧为例
有f[step][i]=sum[step-1][i-1]+sum[step-1][k]-sum[step-1][i]。
 
 #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
const int MAXN = ;
const int MOD = ;
int f[MAXN][MAXN] = {{}};
int n, a, b, k; inline int getnum()
{
char c; int ans = ; bool flag = false;
while ((c = getchar()) == ' ' || c == '\r' || c == '\n');
if (c == '-') flag = true; else ans = c - '';
while ((c = getchar()) >= '' && c <= '') ans = ans * + c - '';
return ans * (flag ? - : );
} inline void add(int &a, int b)
{
ll tmp = (ll)a + b;
if (tmp >= MOD) a = (int)(tmp - MOD);
else if (tmp < ) a = (int)(tmp + MOD);
else a = (int)tmp;
} int main()
{
freopen("lift.in", "r", stdin);
freopen("lift.out", "w", stdout);
n = getnum(); a = getnum(); b = getnum(); k = getnum();
if (fabs(a - b) - == ) { printf("0\n"); return ; }
for (int i = a; i <= n; i++)
f[][i] = ;
for (int step = ; step <= k; step++)
for (int i = ; i <= n; i++)
if (i == b) f[step][i] = f[step][i - ];
else
{
f[step][i] = f[step][i - ];
if (i < b)
{
int x = (b + i) / ;
if ((b + i) % == ) x--;
add(f[step][i], f[step - ][x]);
add(f[step][i], -f[step - ][i]);
add(f[step][i], f[step - ][i - ]);
}
else
{
int x = (b + i) / ;
add(f[step][i], f[step - ][n]);
add(f[step][i], -f[step - ][x]);
add(f[step][i], -f[step - ][i]);
add(f[step][i], f[step - ][i - ]);
}
}
printf("%d\n", f[k][n]);
}
 
 
哇今天的解题报告好短。。
 
 

夏令营提高班上午上机测试 Day 4 解题报告的更多相关文章

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

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

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

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

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

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

  4. nowcoder(牛客网)OI测试赛3 解题报告

    昨天因为胡搞了一会儿社团的事情,所以错过(逃过)了nowcoder的测试赛..... 以上,听说还是普及组难度qwq,而且还有很多大佬AK(然而我这么蒻肯定还是觉得有点难度的吧qwq) 不过我还是日常 ...

  5. 牛客OI赛制测试赛3 解题报告

    前话: 话说考试描述:普及难度. 于是想在这场比赛上涨点信心. 考出来的结果:Point:480     Rank:40 然而同机房的最好成绩是 510. 没考好啊!有点炸心态,D题一些细节没有注意, ...

  6. nowcoder(牛客网)提高组模拟赛第四场 解题报告

    T1 动态点分治 就是模拟..... 但是没有过!! 看了题解之后发现.... 坑点:有可能 \(x<=r\),但是

  7. nowcoder(牛客网)OI测试赛2 解题报告

    qwq听说是一场普及组难度的比赛,所以我就兴高采烈地过来了qwq 然后发现题目确实不难qwq.....但是因为蒟蒻我太蒻了,考的还是很差啦qwq orz那些AK的dalao们qwq 赛后闲来无事,弄一 ...

  8. nowcoder 提高组模拟赛 最长路 解题报告

    最长路 链接: https://www.nowcoder.com/acm/contest/178/A 来源:牛客网 题目描述 有一张 \(n\) 个点 \(m\) 条边的有向图,每条边上都带有一个字符 ...

  9. [jzoj 4668] [NOIP2016提高A组模拟7.19] 腐败 解题报告(质数分类+慢速乘)

    题目链接: http://172.16.0.132/senior/#main/show/4668 题目: 题解: 考虑把A数组里的每个元素分解质因数,对于每个质因数开一个vector存一下包含这个质因 ...

随机推荐

  1. 解决sql和beans中名字不一致问题

    第二图使用别名 tid为sql中的名字,id为beans中的名字,推荐此方式

  2. koala 编译scss不支持中文(包括中文注释),解决方案如下

    进入Koala安装目录,例如:C:\Program Files (x86)\Koala\rubygems\gems\sass-3.4.9\lib\sass 找到engine.rb文件,在该文件中找到最 ...

  3. oracle和mysql分页

    mysql分页 关键字limit,limit m,n 其中m表示起始位置的下标,下标从0开始.n表示要显示的条数,比如要查询一个表的第2到5条数据. ,; oracle分页 关键字rownum, ro ...

  4. Oracle_SQL99_连接查询

    Oracle_SQL99_连接查询 交叉连接 cross join   --交叉连接 cross join --作用:产生两个表的笛卡尔积 select * from emp cross join d ...

  5. b2b2c

    编辑 B2B2C是一种电子商务类型的网络购物商业模式,B是BUSINESS的简称,C是CUSTOMER的简称,第一个B指的是商品或服务的供应商,第二个B指的是从事电子商务的企业,C则是表示消费者.   ...

  6. LAMP和LNMP,你更愿意选择谁,为什么?

    https://www.zhihu.com/question/19697826 http://www.simongong.net lamp 的全称是linux + apache + mysql +ph ...

  7. CSS学习笔记day1

    1.css的简介  css:层叠样式表 (层叠:一层一层的:样式表:很多的属性和属性值) 使页面显示效果更好 将页面内容和显示样式进行分离,提高了显示功能. 2.css和html的结合方式(4种) 在 ...

  8. 【Java框架型项目从入门到装逼】第九节 - 数据库建表和CRUD操作

    1.新建学生表 这节课我们来把和数据库以及jdbc相关的内容完成,首先,进行数据库建表.数据库呢,我们采用MySQL数据库,我们可以通过navcat之类的管理工具来轻松建表. 首先,我们得建一个数据库 ...

  9. java实现最小生成树的prim算法和kruskal算法

    在边赋权图中,权值总和最小的生成树称为最小生成树.构造最小生成树有两种算法,分别是prim算法和kruskal算法.在边赋权图中,如下图所示: 在上述赋权图中,可以看到图的顶点编号和顶点之间邻接边的权 ...

  10. 微信小程序+和风天气完成天气预报

    <冷暖自知>天气小程序 学无止境,以玩儿玩儿的心态去学习! 花半天时间完成简单的小程序应用.适合小程序初学者. 申请小程序帐号: https://mp.weixin.qq.com/wxop ...