BestCoder Round #75 1003 - King's Order & 1004 - King's Game

King's Order

 
 Accepts: 381
 
 Submissions: 1361
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
Problem Description

After the king's speech , everyone is encouraged. But the war is not over. The king needs to give orders from time to time. But sometimes he can not speak things well. So in his order there are some ones like this: "Let the group-p-p three come to me". As you can see letter 'p' repeats for 3 times. Poor king!

Now , it is war time , because of the spies from enemies , sometimes it is pretty hard for the general to tell which orders come from the king. But fortunately the general know how the king speaks: the king never repeats a letter for more than 3 times continually .And only this kind of order is legal. For example , the order: "Let the group-p-p-p three come to me" can never come from the king. While the order:" Let the group-p three come to me" is a legal statement.

The general wants to know how many legal orders that has the length of n

To make it simple , only lower case English Letters can appear in king's order , and please output the answer modulo 10000000071000000007

We regard two strings are the same if and only if each charactor is the same place of these two strings are the same.

Input

The first line contains a number TT10T(T10)——The number of the testcases.

For each testcase, the first line and the only line contains a positive number nn2000n(n2000).

Output

For each testcase, print a single number as the answer.

Sample Input
2
2
4
Sample Output
676
456950

hint:
All the order that  has length 2 are legal. So the answer is 26*26.

For the order that has length 4. The illegal order are : "aaaa" , "bbbb"…….."zzzz" 26 orders in total. So the answer for n == 4 is 26^4-26 = 456950

数位dp,三维数组 dijkd[i][j][k]为处理完 ii 个字符 , 结尾字符为 ′a′ja+j , 结尾部分已重复出现了 kk 次的方案数。转移时当k>=2时,时,d[i][j][k]=d[i-1][j][k-1].

k=1时,d[i][j][1]将d[i-1]中各个字母结尾的各种长度加起来即可。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3
const int N=30;
const int mod=1e9+7;

int d[2001][27][4],n;

int main(){
    int t;
    cin>>t;
    memset(d, 0, sizeof(d));
    for (int i=1; i<=26; i++) {
        d[1][i][1]=1;
    }
    for (int i=2; i<=2000; i++) {
        for (int j=1; j<=26; j++) {
            for (int k=1; k<=26; k++) {
                if (k==j) continue;
                for (int g=1; g<=3&&g<=i; g++) {
                    d[i][j][1]+=d[i-1][k][g];
                    d[i][j][1]%=mod;
                }
                
            }
            for (int k=2; k<=3&&k<=i; k++) {
                d[i][j][k]=d[i-1][j][k-1];
            }
        }
    }
    while (t--) {
        scanf("%d",&n);
        int sum=0;
        for (int i=1; i<=26; i++) {
            for ( int j=1; j<=3; j++) {
                sum+=d[n][i][j];
                sum%=mod;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

King's Game

 
 Accepts: 249
 
 Submissions: 671
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
Problem Description

In order to remember history, King plans to play losephus problem in the parade gap.He calls n1n5000n(1n5000) soldiers, counterclockwise in a circle, in label 123...n1,2,3...n.

The first round, the first person with label 11 counts off, and the man who report number 11 is out.

The second round, the next person of the person who is out in the last round counts off, and the man who report number 22 is out.

The third round, the next person of the person who is out in the last round counts off, and the person who report number 33 is out.

The N - 1 round, the next person of the person who is out in the last round counts off, and the person who report number n1n1 is out.

And the last man is survivor. Do you know the label of the survivor?

Input

The first line contains a number T0T5000T(0<T5000), the number of the testcases.

For each test case, there are only one line, containing one integer nn, representing the number of players.

Output

Output exactly TT lines. For each test case, print the label of the survivor.

Sample Input
2
2
3
Sample Output
2
2

Hint:
For test case #1:the man who report number 11 is the man with label 11, so the man with label 22 is survivor.

For test case #1:the man who report number 11 is the man with label 11, so the man with label 1 is out. Again the the man with label 2 counts 11,  the man with label 33 counts 22, so the man who report number 22 is the man with label 33. At last the man with label 22 is survivor.
题解都说是约瑟夫问题,可是我并不知道什么是约瑟夫问题……借一下官网题解:

裸的约瑟夫是怎么玩的:nn 个人,每隔 kk 个删除。

由于我们只关心最后一个被删除的人,并不关心最后的过程,所以,我们没有必要也不能够模拟整个过程。我们用递推解决。假设有nn个人围成环,标号为0n1[0,n1]00开始的好处是取模方便),每数kk个人杀一个的情况下,最后一个存活的人的编号是fnf[n]

我们有f10f[1]=0,这不需要解释。

接着考虑一般情况fnf[n],第一个杀死的人的编号是k1k1,杀死后只剩下n1n1个人了,那么我们重新编号!

原来编号为k的现在是00号,也就是编号之间相差33。我们只要知道现在n1n1个人的情况最后是谁幸存也就知道nn个人的情况是谁幸存。幸运的是fn1f[n1]已经算出来了那fnf[n]就是在fn1f[n1]的基础上加上一个kk即可不要忘记总是要取模。

https://i-blog.csdnimg.cn/blog_migrate/dd08820945ffd7b3ef2924268079faad.png

所以递推式子是: fii1otherf[i]={ 0                      i=1 (f[i - 1] + k) mod i       other

此题只用在原版约瑟夫问题上加一维,由于依次隔 123...n11,2,3...n1 个人删除,所以用 fijf[i][j] 表示 ii 个人,依次隔 jj1...ji1j,j+1...j+i1 个人的幸存者标号。

根据刚才的重标号法,第一次 j1j1 号出局,从 jj 开始新的一轮,从  j1j+1 开始清除,剩余 i1i1 个人,也有递推式子:

fiji1otherf[i][j]={ 0                      i=1 (f[i - 1][j+1] + j) mod i       other

答案就是 fn11f[n][1]+1(将标号转移到 1n[1,n]),问题轻松解决。


题意已经说明的很清楚了,解法也很清楚,但题解说的滚动数组就没有悟到,而开5000^2数组爆了内存。后来发现有不用滚动数组的解法,就借来了。具体其实就是一个一个算,并不需要二维数组。学习了一个约瑟夫问题。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3
const int N=30;
const int mod=1e9+7;

int f[5005],ans[5005],n;

int solve(int n){
    f[1]=0;
    int k=n-1;
    for (int i=2; i<=n; i++) {
        f[i]=(f[i-1]+(k--))%i;
    }
    return f[n]+1;
}

int main(){
    int t;
    cin>>t;
    memset(f, 0, sizeof(f));
    ans[0]=0;
    ans[1]=1;
    for (int i=2; i<=5000; i++) {
        ans[i]=solve(i);
    }
    while (t--) {
        scanf("%d",&n);
        cout<<ans[n]<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。
### 内容概要 这份《计算机试卷1》包含多个部分,主要覆盖了计算机基础知识、操作系统应用、文字处理、电子表格、演示文稿制作、互联网应用以及计算机多媒体技术。试卷以单选题开始,涉及计算机历史、基本概念、硬件组成、软件系统、网络协议等。接着是操作应用部分,要求考生在给定的软件环境中完成一系列具体的计算机操作任务。 ### 适用人群 本试卷适用于计算机科学与技术、信息技术相关专业的学生,以及准备计算机水平考试或职业资格认证的人士。它适合那些希望检验和提升自己计算机操作能力的学习者,也适用于教育工作者作为教学评估工具。 ### 使用场景及目标 1. **学习评估**:作为教育机构的课程评估工具,帮助教师了解学生对计算机基础知识的掌握程度。 2. **自学检验**:供个人自学者检验自己的计算机操作技能和理论知识,为进一步学习提供方向。 3. **职业发展**:为职场人士提供计算机技能的自我提升途径,增强其在信息时代的竞争力。 4. **考试准备**:为准备计算机相关考试的考生提供实战演练的机会,加强考试自信。 5. **教学资源**:教师可以将其作为教学资源,设计课程和实验,提高教学效果。 试卷的目标是通过理论知识的测试和实践技能的操作,全面提升考生的计算机应用能力。考生应掌握从基础的计算机组成原理到复杂的数据处理、演示文稿制作、网络应用以及多媒体技术处理等多方面技能。通过本试卷的学习与练习,考生将能够更加熟练地使用计算机解决实际问题,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值