zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Android 引用资源
    Android res目录结构
    Android 目录结构
    ubuntu 14.04 (desktop amd 64) 查看配置参数
    ros service
    install ros-indigo-map-server
    python 单例
    查看指定目录空间占用
    shell 设置超时时间
    nohup 不生成 nohup.out的方法
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7384113.html
Copyright © 2011-2022 走看看