NOIP模拟17.8.17

NOIP模拟17.8.17

A 小 G 的字符串
文件名 输入文件 输出文件 时间限制 空间限制
str.pas/c/cpp str.in str.out 1s 128MB
【题目描述】
有一天,小 L 给小 G 出了这样一道题:生成一个长度为 n 的、全由小写英文
字母构成的字符串,只能使用 k 种字母。要求满足:
• 字符串中相邻的两个字母不能相同。
• 必须出现恰好 k 种不同的字母。
这样的合法字符串可能有很多,小 L 让小 G 输出字典序最小的那个。
小 G 太笨啦,不会做这道题,希望你帮帮他。
【输入格式】
输入文件只有两个数字 n, k,含义如题。
【输出格式】
输出文件共一行,输出合法的字典序最小的字符串。
如果不存在任意一个合法的方案,输出 −1。
【样例输入】
7 4
【样例输出】
ababacd
【数据范围】
对于 100% 的数据,1 ≤ n ≤ 105, 1 ≤ k ≤ 26

【题解】

注意特判。我忘记了k == 1 && n != 1的情况。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5
 6 const int MAXN = 100000 + 10;
 7
 8 int n,k;
 9 char s[MAXN];
10
11 int main()
12 {
13     scanf("%d %d", &n, &k);
14     if(k > n || k == 0 || n == 0 || (k == 1 && n != 1))
15     {
16         printf("-1");
17         return 0;
18     }
19     else if(k == 1)
20     {
21         for(register int i = 1;i <= n;++ i)printf("%c", ‘a‘);
22         return 0;
23     }
24     else if(k == 2)
25     {
26         for(register int i = 1, j = 0;i <= n;++ i, j ^= 1)printf("%c", ‘a‘ + j);
27         return 0;
28     }
29     register int p = 1, j;
30     for(p = n, j = 0;p > k - 2;-- p, j ^= 1)
31         printf("%c", ‘a‘ + j);
32     for(j = 1;p >= 1;-- p,++ j)
33         printf("%c", ‘b‘ + j);
34     return 0;
35 }

T1

B 小 G 的城堡
文件名 输入文件 输出文件 时间限制 空间限制
castle.pas/c/cpp castle.in castle.out 1s 128MB
【题目描述】
小 G 家有一座城堡。城堡里面有 n 个房间,每个房间上都写着一个数字 pi。
小 G 拉着几个小伙伴在城堡里面玩耍,他们约定,如果某个人当前站在 i 房间里
面,下一步这个人就会去 pi 房间,再下一步这个人去 ppi。
为了增加趣味性,小 G 想重新书写每个房间的 pi,以满足:
• 如果从编号 1 到 k 中的某个房间开始,按照规则走,必须能够走到 1 号房间。
特别地,如果从 1 号房间开始走,也要能够走回 1 号房间(至少走一步,如
果 p1 = 1,从 1 走到 1 也算合法)。
• 如果从编号大于 k 的某个房间开始,按照规则走,一定不能走到 1 号房间。
小 G 想知道,有多少种书写 pi 的方案,可以满足要求。
【输入格式】
输入文件一行两个数字 n, k,含义如题。
【输出格式】
输出文件一个数字,表示合法的方案数。答案对 109 + 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)。

【题解】

我们发现,前k个点肯定和前k个点互相连边。后n-k个点肯定不会连到

前k个点里面去。
所以,我们只要爆搜前k个点连接的方案,然后检查;后n-k个点,只要

连的是后n-k个点,爱怎么连怎么连,方案数是(n-k)^(n-k)。最后把两

部分方案数乘起来就行。——tygg

但同时,我们发现:前k个点有规律:n^(n - 1)

不知是否正确

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5
 6 const long long MOD = 1000000000 + 7;
 7
 8 inline void read(long long& x)
 9 {
10     x = 0;char ch = getchar(), c = ch;
11     while(ch < ‘0‘ || ch > ‘9‘)c = ch, ch = getchar();
12     while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘, ch = getchar();
13     if(c == ‘-‘)x = -x;
14 }
15
16 long long n,k,ans;
17
18 long long pow(long long a, long long b)
19 {
20     long long r = 1, base = a%MOD;
21     for(;b;b >>= 1)
22     {
23         if(b & 1)r *= base, r %= MOD;
24         base *= base, base %= MOD;
25     }
26     return r;
27 }
28
29 int main()
30 {
31     read(n);read(k);
32     ans = pow(k, k - 1)%MOD;
33     printf("%lld", (ans * pow(n - k, n - k))%MOD);
34     return 0;
35 }

T2

C 小 G 坐电梯
文件名 输入文件 输出文件 时间限制 空间限制
lift.pas/c/cpp lift.in lift.out 2s 128MB
【题目描述】
小 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。

【题解】

第二遍做这个题了,之前在清北澡堂现场AC过,结果今天偷了个懒,愉快的忘了s > t的情况,挂了30分(感谢天宇哥哥数据手下留情)

令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
// 博主注:可以直接写i + (B - I - 1)/2

n<=5000
这样就不能用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]
——gty

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5
 6 const int MAXN = 10000 + 10;
 7 const int MAXK = 5000 + 10;
 8 const long long MOD = 1000000000 + 7;
 9
10 int n,s,t,k;
11 long long dp[5][MAXN];
12
13 int main()
14 {
15     scanf("%d %d %d %d", &n, &s, &t, &k);
16     register int p = 1;
17     if(s <= t)
18     {
19         for(register int i = s;i < t;++ i)
20             dp[0][i] = 1;
21         for(register int i = 1;i <= k;++ i, p ^= 1)
22             for(register int j = 1;j < t;++ j)
23                 dp[p][j] = ((dp[p][j - 1] + dp[p ^ 1][j + (t - j - 1) / 2])%MOD - (dp[p ^ 1][j] - dp[p ^ 1][j - 1] + MOD)%MOD+MOD)%MOD;
24         printf("%lld", dp[p^1][t - 1]%MOD);
25     }
26     if(s > t)
27     {
28         for(register int i = s;i > t;-- i)
29             dp[0][i] = 1;
30         for(register int i = 1;i <= k;++ i, p^= 1)
31             for(register int j = n;j > t;-- j)
32                 dp[p][j] = ((dp[p][j + 1] + dp[p ^ 1][t + (j - t + 2) / 2])%MOD - (dp[p ^ 1][j] - dp[p ^ 1][j + 1] + MOD)%MOD+MOD)%MOD;
33         printf("%lld", dp[p^1][t + 1]%MOD);
34     }
35     return 0;
36 }

T3

时间: 2024-12-12 03:28:04

NOIP模拟17.8.17的相关文章

noip 模拟赛 After 17(递推+特殊的技巧)

来源:Violet_II T1 好神的一题,我竟然没做出来QAQ 首先我们发现,答案是sigma(x[i]*x[j], i>j)+sigma(y[i]*y[j], i>j).显然只需要讨论左边的就行了,右边就可以同理了. 我们发现sigma(x[i]*x[j], i>j)=(sigma(x[i])^2-sigma(x[i]^2))/2,减号后边和除以2显然是常数也就是说确定了x[i]也就确定了值.但是x[i]的值有哪些可以取呢?我们发现在sigma(x[i]*x[j], i>j)中

NOIP模拟 17.8.18

NOIP模拟17.8.18 A.小菜一碟的背包[题目描述]Blice和阿强巴是好朋友但萌萌哒Blice不擅长数学,所以阿强巴给了她一些奶牛做练习阿强巴有 n头奶牛,每头奶牛每天可以产一定量的奶,同时也需要一定量的草作为饲料对于第 i头奶牛来说,它每天可以产 vi升的奶,同时需要 wi千克的草作为饲料现在来自蚯蚓国的九条可怜想借一些奶牛,使借走的这些奶牛每天的总产奶量最大,但九条可怜很穷,每天最多只能提供W千克的草作为饲料,而且她还需要对付跳蚤国的神刀手,所以她把这个问题交给了阿强巴,不不不……阿

NOIP模拟17.9.21

NOIP模拟17.9.21 1 任务安排manage.in/.out/.cpp1.1 问题描述你有N 个工作,同一时刻只能做一个任务, 其中每个工作有其所需时间, 及完成的Deadline(截止时间), 问要完成所有工作, 最迟要从什么时候开始.你最早可以从时间0 开始工作.1.2 输入格式第一行一个整数N,表示任务数量接下来n 行,每行两个整数,Ti; Si,分别表示该任务的持续时间和截止时间.1.3 输出格式输出一个整数,表示最晚的开始时间,如果不能完成,输出-1.1.4 样例输入43 58

NOIP模拟17.9.22

NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥ ??的位置去,但很不幸数轴上有??个区间是禁区,不能进入.青蛙会选择一个长度??,从原点开始每次向右跳长度为??的一段.一路上青蛙会停的位置是0, ??, 2??,…直到跳到了≥ ??的位置,任意一个位置都不能在禁区中.请求出??的最小值,注意??可以是实数.[输入格式]输入文件为susume.in.输入文件的第一行包含两个整数??和??,含义如问题描述中所述.接下来??行,每行描述一个禁区.每行有两个整数

NOIP模拟 6.28

NOIP模拟赛6.28 Problem 1 高级打字机(type.cpp/c/pas) [题目描述] 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序,支持如下3种操作: 1.T x:在文章末尾打下一个小写字母x.(type操作) 2.U x:撤销最后的x次修改操作.(Undo操作) (注意Query操作并不算修改操作) 3.Q x:询问当前文章中第x个字母并输出.(Query操作) 文章一开始可以视为空串. [输入格式]

NOIP模拟赛 6.29

2017-6-29 NOIP模拟赛 Problem 1 机器人(robot.cpp/c/pas) [题目描述] 早苗入手了最新的Gundam模型.最新款自然有着与以往不同的功能,那就是它能够自动行走,厉害吧. 早苗的新模型可以按照输入的命令进行移动,命令包括‘E’.‘S’.‘W’.‘N’四种,分别对应东南西北.执行某个命令时,它会向对应方向移动一个单位.作为新型机器人,它可以执行命令串.对于输入的命令串,每一秒它会按命令行动一次.执行完命令串的最后一个命令后,会自动从头开始循环.在0时刻时机器人

liu_runda 给辣鸡蒟蒻做的 NOIP模拟赛 1.0 第二题 任(duty) 题解

问题 B: 任(duty) 时间限制: 2 Sec  内存限制: 512 MB 题目描述 liu_runda退役之后就失去梦想开始咸鱼生活了- Bilibili夏日画板活动中,所有人都可以在一块画板上进行像素画创作.UOJ群有一群无聊的人决定在画板上创作一个50*50的UOJ的LOGO.如下图. 这块画板实际上是很大的矩形网格.一个网格是一像素. 一个人每三分钟才能画一个像素.所以liu_runda的咸鱼生活非常无聊. 郭神表示他实在是看不下去liu_rudna这只颓狗了,于是随手出了一道神题,

noip模拟测试11

T1:string 第一眼秒出思路,这不就是排序那道题的加强版吗? 然而歪?解复杂度虽然是对的,但常数过大,竟被卡到70 歪?解:(实际上std写的就是这个,但据说std被卡掉了 OAO) 因为字符集很小,所以我们可以把区间排序改为区间查询和覆盖 即:先查询区间内所有字符的个数,再从左端点开始按照大小关系依次将长度为字符个数的区间修改为该字符. 期望复杂度O ( 26*mlogn ),实际复杂度O ( 26*mlogn*(巨大的常数) ) 所以需要一(feng)定(kuang)的卡常 正?解:

noip模拟测试21

T1:折纸 这道写崩我也是没话说…… 模拟就完了,记录每次的折叠点,每次将之前的都扫一遍就完了 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cmath> 5 #include<algorithm> 6 #include<cstdlib> 7 #define ll long long 8 using namespace std; 9 con