8.12 小组解题
A工艺 | ||
|
问题描述
小敏和小燕是一对好朋友。
他们正在玩一种神奇的游戏,叫Minecraft。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想,在仅这一个操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样那么谁的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一样,那么这两个工艺品就一样漂亮。
输入格式
第一行两个整数n,代表方块的数目。
第二行n个整数,每个整数按从左到右的顺序输出方块瑕疵度的值。
输出格式
一行n个整数,代表最美观工艺品从左到右瑕疵度的值。
样例输入
10
10 9 8 7 6 5 4 3 2 1
样例输出
1 10 9 8 7 6 5 4 3 2
提示
【数据规模与约定】
对于20%的数据,n<=1000
对于40%的数据,n<=10000
对于100%的数据,n<=300000
B【SDOI2008】Sandy的卡片 | |
|
问题描述
Sandy和Sue的热衷于收集干脆面中的卡片。
然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型。
每一张卡片都由一些数字进行标记,第i张卡片的序列长度为Mi,要想兑换人物模型,首先必须要集够N张卡片,对于这N张卡片,如果他们都有一个相同的子串长度为k,则可以兑换一个等级为k的人物模型。相同的定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串。
Sandy的卡片数远远小于要求的N,于是Sue决定在Sandy的生日将自己的卡片送给Sandy,在Sue的帮助下,Sandy终于集够了N张卡片,但是,Sandy并不清楚他可以兑换到哪个等级的人物模型,现在,请你帮助Sandy和Sue,看看他们最高能够得到哪个等级的人物模型。
输入格式
第一行为一个数N,表示可以兑换人物模型最少需要的卡片数,即Sandy现在有的卡片数
第i+1行到第i+N行每行第一个数为第i张卡片序列的长度Mi,之后j+1到j+1+Mi个数,用空格分隔,分别表示序列中的第j个数
输出格式
一个数k,表示可以获得的最高等级。
样例输入
2
2 1 2
3 4 5 9
样例输出
2
提示
30%的数据保证n<=50
100%的数据保证n<=1000,m<=200
CCow XOR奶牛异或 | |
|
问题描述
农民约翰在喂奶牛的时候被另一个问题卡住了。他的所有N(1 <= N <= 100,000)个奶牛在他面前排成一行(按序号1..N的顺序),按照它们的社会等级排序。奶牛#1有最高的社会等级,奶牛#N最低。每个奶牛同时被指定了一个不唯一的附加值,这个数在0..2^21 - 1的范围内。
帮助农民约翰找出应该从哪一头奶牛开始喂,使得从这头奶牛开始的一个连续的子序列上,奶牛的附加值的异或最大。
如果有多个这样的子序列,选择结尾的奶牛社会等级最高的。如果还不唯一,选择最短的。
输入格式
第1行:一个单独的整数N。
第2到N + 1行:N个0..2^21 - 1之间的整数,代表每头奶牛的被赋予的数。第j行描述了社会等级j - 1的奶牛。
输出格式
第 1 行: 3个空格隔开的整数,分别为:最大的异或值,序列的起始位置、终止位置。 时限0.5秒
样例输入
5
1
0
5
4
2
样例输出
6 4 5
提示
最大异或值为6,从第4个开始喂,到第5个结束。
4 异或 2 = 6
(100) 异或 (010) = (110)
D拉拉队排练 | ||
|
问题描述
艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了。拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛。所以作为拉拉队队长的楚雨荨同学知道,帮助篮球队训练好拉拉队有多么的重要。拉拉队的选拔工作已经结束,在雨荨和校长的挑选下,n位集优秀的身材、舞技于一体的美女从众多报名的女生中脱颖而出。这些女生将随着篮球队的小伙子们一起,和对手抗衡,为艾利斯顿篮球队加油助威。
一个阳光明媚的早晨,雨荨带领拉拉队的队员们开始了排练。n个女生从左到右排成一行,每个人手中都举了一个写有26个小写字母中的某一个的牌子,在比赛的时候挥舞,为小伙子们呐喊、加油。雨荨发现,如果连续的一段女生,有奇数个,并且他们手中的牌子所写的字母,从左到右和从右到左读起来一样,那么这一段女生就被称作和谐小群体。
现在雨荨想找出所有和谐小群体,并且按照女生的个数降序排序之后,前K个和谐小群体的女生个数的乘积是多少。由于答案可能很大,雨荨只要你告诉她,答案除以19930726的余数是多少就行了。
输入格式
第一行为两个正整数n和K,代表的东西在题目描述中已经叙述。
接下来一行为n个字符,代表从左到右女生拿的牌子上写的字母。
输出格式
输出一个整数,代表题目描述中所写的乘积除以19930726的余数,如果总的和谐小群体个数小于K,输出一个整数-1。
样例输入 1
5 3
ababa
样例输出 1
45
样例输入 2
100 84
baaababaaaabaabaaaababbabaababaaabaabaabbbbabbaaaababbabaaabaaabbaaaaaaaaababbbbabbbbbbababbabbaabba
样例输出 2
461075
提示
【样例说明】
和谐小群体女生所拿牌子上写的字母从左到右按照女生个数降序排序后为ababa, aba, aba, bab, a, a, a, b, b,前三个长度的乘积为。
#include<bits/stdc++.h> #define mod 19930726ll using namespace std; string s; long long n,k,len[1000005],r[1000005],l,tot,ans=1,sum; long long ksm(long long a, long long n, long long c){ long long ans=1; a=a%c; while(n){ if(n&1)ans=(ans*a)%c; n=n>>1; a=(a*a)%c; } return ans; } void manachar() { l=s.length(); long long cnt=0,maxlen=0; len[1]++; for(int i=1;i<l;i++){ if(i<=maxlen)r[i]=min(r[2*cnt-i],maxlen-i+1); else r[i]=1; while((s[i-r[i]]==s[i+r[i]]))r[i]++; if(maxlen<=i+r[i]-1){cnt=i;maxlen=i+r[i]-1;} len[r[i]*2-1]++; } } int main() { cin>>n>>k; cin>>s; s='&'+s; manachar();//找出个数 for(long long i=l;i>0;i--) { if(i&1) { sum+=len[i]; ans=ans*ksm(i,min(sum,k-tot),mod)%mod; tot+=sum; if(tot>=k){cout<<ans;return 0;} } } cout<<"-1"; }
这道题就是马拉车 但是要注意的一点是当搜索到一串字符是回文时,需要再次把-2 -4……的情况加上
E【NOI2014 Day2】动物园 | |
|
问题描述
近日,园长发现动物园中好吃懒做的动物越来越多了。例如企鹅,只会卖萌向游客要吃的。为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法。
某天,园长给动物们讲解KMP算法。
园长:“对于一个字符串S,它的长度为L。我们可以在O(L)的时间内,求出一个名为next的数组。有谁预习了next数组的含义吗?”
熊猫:“对于字符串S的前i个字符构成的子串,既是它的后缀又是它的前缀的字符串中(它本身除外),最长的长度记作next[i]。”
园长:“非常好!那你能举个例子吗?”
熊猫:“例S为abcababc,则next[5]=2。因为S的前5个字符为abcab,ab既是它的后缀又是它的前缀,并且找不到一个更长的字符串满足这个性质。同理,还可得出next[1] = next[2] = next[3] = 0,next[4] = next[6] = 1,next[7] = 2,next[8] = 3。”
园长表扬了认真预习的熊猫同学。随后,他详细讲解了如何在O(L)的时间内求出next数组。
下课前,园长提出了一个问题:“KMP算法只能求出next数组。我现在希望求出一个更强大num数组一一对于字符串S的前i个字符构成的子串,既是它的后缀同时又是它的前缀,并且该后缀与该前缀不重叠,将这种字符串的数量记作num[i]。例如S为aaaaa,则num[4] = 2。这是因为S的前4个字符为aaaa,其中a和aa都满足性质‘既是后缀又是前缀’,同时保证这个后缀与这个前缀不重叠。而aaa虽然满足性质‘既是后缀又是前缀’,但遗憾的是这个后缀与这个前缀重叠了,所以不能计算在内。同理,num[1] = 0,num[2] = num[3] = 1,num[5] = 2。”
最后,园长给出了奖励条件,第一个做对的同学奖励巧克力一盒。听了这句话,睡了一节课的企鹅立刻就醒过来了!但企鹅并不会做这道题,于是向参观动物园的你寻求帮助。你能否帮助企鹅写一个程序求出num数组呢?
特别地,为了避免大量的输出,你不需要输出num[i]分别是多少,你只需要输出对1,000,000,007取模的结果即可。
其中
输入格式
第1行仅包含一个正整数n,表示测试数据的组数。
随后n行,每行描述一组测试数据。每组测试数据仅含有一个字符串S,S的定义详见题目描述。
数据保证S中仅含小写字母。输入文件中不会包含多余的空行,行末不会存在多余的空格。
输出格式
包含n行,每行描述一组测试数据的答案,答案的顺序应与输入数据的顺序保持一致。
对于每组测试数据,仅需要输出一个整数,表示这组测试数据的答案对1,000,000,007取模的结果。输出文件中不应包含多余的空行。
样例输入
样例输入1:
3
aaaaa
ab
abcababc
大样例点击<a href="http: pan.baidu.com="" s="" 1ntlqxw1"="">这里下载
样例输出
36
1
32
提示
样例解释:
"aaaaa":num[1] = 0, num[2] = 1, num[3] = 1, num[4] = 2, num[5] = 2.
"ab": num[1] = 0, num[2] = 0.
"abcababc": num[1] = 0, num[2] = 0, num[3] = 0, num[4] = 1, num[5] = 1, num[6] = 1, num[7] = 1, num[8] = 1.
数据范围:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include<bits/stdc++.h> #define mod 1000000007 using namespace std; char ch[1000005]; long long ans; int fail[1000005],num[1000005],n,j; void kmp() { n=strlen(ch+1); j=0;num[1]=1; for ( int i=2;i<=n;i++) { while (ch[j+1]!=ch[i]&&j)j=fail[j]; if (ch[j+1]==ch[i])j++; fail[i]=j; num[i]=num[j]+1; } j=0; for ( int i=2;i<=n;i++) { while (j&&ch[j+1]!=ch[i])j=fail[j]; if (ch[i]==ch[j+1])j++; while ((j<<1)>i&&j)j=fail[j]; ans*=num[j]+1; ans%=mod; } } int main() { int n; cin>>n; for ( int i=1;i<=n;i++) { ans=1; scanf( "%s" ,ch+1); kmp(); cout<<ans<<endl; } } |
这道题就是用kmp 不过要加上处理一个num数组
F公共串 | ||
|
问题描述
给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务:
l 读入单词
l 计算最长公共子串的长度
l 输出结果
输入格式
第一行是整数 n,1<=n<=5,表示单词的数量。
接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
输出格式
仅一行,一个整数,最长公共子串的长度。
样例输入
3
abcb
bca
acbc
样例输出
2
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步