T1 远征

题目

【题目描述】

寒枫将军将要带领他的部队去圣雪山消灭那里的冰龙。部队分成了若干个小队,属于同一个小队的人兵种相同。

寒枫将军有着杰出的指挥能力,在战斗的时候,寒枫将军能够让所有相同兵种的人互相配合,使t个相同兵种的人发挥出t2的战斗力;

寒枫将军还能让不同兵种的人互相配合,使整个部队的战斗力是所有兵种战斗力的和。

例如,部队中有3个小队,分别是5个人的步兵小队,3个人的步兵小队,3个人的骑兵小队。那么步兵战斗力为64,骑兵战斗力为9,部队总战斗力为73。

寒枫将军需要知道他的部队的战斗力是多少。

【输入格式】

第一行一个整数n,表示小队数。接下来n行,第i行有两个整数ai、bi,表示这个小队有ai个人,兵种为bi

【输出格式】

一行一个整数,部队的战斗力。

【输入样例】

3

5 1

3 1

3 2

【输出样例】

73

【数据规模】

10%的数据,n=1

30%的数据,n≤1000

另有20%的数据,ai=1

另有30%的数据,bi≤1000

100%的数据,1≤n≤100000,1≤ai≤10000,1≤bi≤1,000,000,000

解析

T1依旧水,蒟蒻仍AC。

将a与b用结构体存储,再按b从小到大排序,如果i的b等于i-1的b,那就是相同兵种,令t累加上a,

如果不相等,那就是不同兵种,统计一下答案并把t清零,最后不要忘了再统计一次答案。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
struct rec{
int a,b;
}ra[];
int n;
long long ans,t;
bool cmp(rec x,rec y)
{
return x.b<y.b;
}
int main()
{
//freopen("expedition.in","r",stdin);
//freopen("expedition.out","w",stdout);
n=read();
for(int i=;i<=n;i++) ra[i].a=read(),ra[i].b=read();
sort(ra+,ra+n+,cmp);
t=ra[].a;
for(int i=;i<=n;i++)
{
if(ra[i].b==ra[i-].b) t+=ra[i].a;
else
{
ans+=t*t;
t=ra[i].a;
}
}
ans+=t*t;
cout<<ans;
return ;
//fclose(stdin);
//fclose(stdout);
}

T2 密码

题目

【题目描述】

假发通过了不懈的努力,得到了将军家门锁的密码(一串小写英文字母)。但是假发被十四和猩猩他们盯上了,所以假发需要把密码传递出去。

因为假发不想十四他们发现几松门前贴的小纸条就是将军家的密码,所以他加密了密码(新八:听起来有点诡异)。加密方法如下:随机地,在密码中任意位置插入随机长度的小写字符串。

不过,假发相信银桑和他那么多年小学同学,一定能猜中密码是什么的(新八:银桑什么时候成攮夷志士了!!!)。

可是,写完了小纸条之后,假发觉得有点长,就想截去头和尾各一段(可以为空),让剩下的中间那一段依然包含真~密码。想着想着,假发就想知道有多少种可行方案。

结果在沉迷于稿纸之际,假发被投进了狱门岛(新八:……)。于是,就由你计算了。

【输入格式】

两行非空字符串,纯小写英文字母,第一行是加密后的密码,第二行是原密码。

第一行长度不超过300000,第二行不超过200。

【输出格式】

一行,有多少种方案。注意:不剪也是一种方案。

【输入样例】

abcabcabc

cba

【输出样例】

9

【数据规模】

30%的数据满足第一行长度不超过1000。

100%的数据满足第一行长度不超过300000,方案总数不超过10^18。

第二行长度小于213

解析

感谢机房大佬们的教学!

我们设f[i][j](初值为-1)表示加密后密码的第i位与原密码的第j位匹配时,加密后密码与原密码匹配的第0位数在加密后密码的位上的左边共有多少位(从第0位开始),

很绕对不对(本蒟蒻也看不懂自己在写什么),举个例子,abcabcabc与cba这个样例,

f[2][0]=2(加密后密码第2位与原密码第0位都是c,匹配,而在原密码第0位c对应的加密后密码第2位的前面共有2位),还是不懂?再多看几个例子,

f[3][1]=2(加密后密码第3位是a,而原密码第1位为b,不匹配,所以还是2),

f[4][1]=2(加密后密码第4位与原密码第1位都是b,匹配),

f[6][2]=2(加密后密码第6位与原密码第2位都是a,匹配,而在原密码第0位c对应的加密后密码的第2位的前面共有2位)。如果还不懂的话多看几遍、多试几遍。

然后状态转移即可,最后答案是所有f[i][原密码长度-1]+1的和(i从加密后密码长度-1枚举到原密码长度-1)。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int f[][];
string s1,s2;
long long ans;
int main()
{
//freopen("substring.in","r",stdin);
//freopen("substring.out","w",stdout);
memset(f,-,sizeof(f));
cin>>s1>>s2;
for(int i=;i<s1.size();i++)
for(int j=;j<s2.size();j++)
{
if(j==)
{
if(s1[i]==s2[j]) f[i][]=i;
if(s1[i]!=s2[j]&&i>=) f[i][]=f[i-][];
}
else
{
if(s1[i]==s2[j]&&i>=) f[i][j]=f[i-][j-];
if(s1[i]!=s2[j]&&i>=) f[i][j]=f[i-][j];
}
}
for(int i=s1.size()-;i>=s2.size()-;i--) ans+=f[i][s2.size()-]+;
cout<<ans;
return ;
//fclose(stdin);
//fclose(stdout);
}

T3 独立集

题目

【题目描述】

有一天,一个名叫顺旺基的程序员从石头里诞生了。又有一天,他学会了冒泡排序和独立集。在一个图里,独立集就是一个点集,满足任意两个点之间没有边。

于是他就想把这两个东西结合在一起。众所周知,独立集是需要一个图的。那么顺旺基同学创造了一个算法,从冒泡排序中产生一个无向图。

这个算法不标准的伪代码如下:

Pascal版本

C/C++版本

procedure bubblesortgraph(n, a[]) :

/*输入:点数n,1到n的全排列a。

输出:一个点数为n的无向图G。*/

创建一个有n个点,0条边的无向图G。

repeat

swapped = false

for i 从 1 到 n-1 :

if a[i] > a[i + 1] :

在G中连接点a[i]和点a[i + 1]

交换a[i]和a[i + 1]

swapped = true

until not swapped

输出图G。

//结束。

void bubblesortgraph(n,a[])

//输入:点数n,1到n的全排列a

//输出:一个点数为n的无向图G

{  创建一个有n个点,0条边的无向图G。

do{  swapped=false

for i 从1 到n-1

if(a[i]>a[i+1])

{  在G中连接点a[i]和点a[i+1]

交换a[i]和a[i+1]

swapped =true

}

}while(swapped);

输出图G。

}

//结束。

那么我们要算出这个无向图G最大独立集的大小。但是事情不止于此。顺旺基同学有时候心情会不爽,这个时候他就会要求你再回答多一个问题:

最大独立集可能不是唯一的,但有些点是一定要选的,问哪些点一定会在最大独立集里。今天恰好他不爽,被他问到的同学就求助于你了。

【输入格式】

输入包含两行,第一行为N,第二行为1到N的一个全排列。

【输出格式】

输出包含两行,第一行输出最大独立集的大小,第二行从小到大输出一定在最大独立集的点的编号。

【输入样例】

3

3 1 2

【输出样例】

2

2 3

【数据规模】

30%的数据满足 N<=16

60%的数据满足 N<=1,000

100%的数据满足 N<=100,000

解析

这题有点坑,刚看的时候想都没想,直接打了模拟,结果GG,后来想想才发现是最长上升子序列。

仔细看冒泡排序的代码,不难得出,只有两数为逆序对时才有边,反之没边,即上升子序列,而第一问显然就是最长上升子序列;

而第二问就可以转化为必定会在最长上升子序列的元素有哪些,我们可以正着求一遍最长上升子序列,再反向求一遍,

两个最长上升子序列都有的元素即为答案。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
const int N=;
int n,a[N],k,maxn,f1[N],f2[N],d[N],b[N];
int main()
{
//freopen("bubble.in","r",stdin);
//freopen("bubble.out","w",stdout);
n=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++)
{
k=lower_bound(d,d+maxn+,a[i])-d;
maxn=max(maxn,k);
f1[i]=k;
d[k]=a[i];
}
d[]=0xcfcfcfcf,maxn=;
for(int i=n;i>=;i--)
{
k=lower_bound(d,d+maxn+,-a[i])-d;
maxn=max(maxn,k);
f2[i]=k;
d[k]=-a[i];
}
cout<<maxn<<endl;
for(int i=;i<=n;i++)
if(f1[i]+f2[i]-==maxn) b[f1[i]]++;
for(int i=;i<=n;i++)
if(f1[i]+f2[i]-==maxn&&b[f1[i]]==) cout<<i<<" ";
return ;
//fclose(stdin);
//fclose(stdout);
}

T4 选修课

题目

【题目描述】

温州中学开放了许多选修课,每节选修课都属于一种种类。精力旺盛的黄小龙同学想要尽可能多的参加选修课,但是他只能选择M种种类的课程。

当然,对于他所选的种类,他会去上所有该种类的课。现在他想知道他最多能上几节选修课,以及上最多选修课的方案数。

两种方案被认为不同当且仅当一种方案中存在另一种方案所没有的选修课。

【输入格式】

第一行一个只由小写字母组成,长度为N的字符串。表示有N节选修课,以及每节选修课的种类。

【输出格式】

输出一行,两个用空格隔开的正整数,分别表示最多选修课数量和方案数。

【输入样例】

abcde

1

【输出样例】

1 5

【数据规模】

对于30%的数据,M==1;

对于另外30%的数据,每种种类的选修课最多只有一节;

对于100%的数据1<=M<=26、1<=N<=100000;

解析

惊!某蒟蒻AC了T4!

今天的T4居然挺简单,有点不可思议。

因为字母总共只有26个,所以我们可以开一个a数组存储每个字母出现的次数,

再用贪心思想,把a数组从大到小排序,取前m个数累加就是第一问;

第二问得分两种情况,如果m≥所有字母种类,直接输出1即可;

如果m<所有字母种类的话,其实就是在求组合数,举个例子,

aaaabbbbcccdddeeffz(这些是字母出现次数,别问我为什么这么规则,反正只要记录出现次数就可以了(其实是懒)),

很显然,a4次,b4次,c3次,d3次,e2次,f2次,z1次。

如果m为1,在a和b两个中选一个即可,方案数为2;

如果m为2,很显然,取a和b这两个出现次数最多的即可,方案数为1,;

如果m为3呢?很显然,a和b这两个字母肯定必选,那么剩下的一个肯定得选c或d,方案数为2,是不是和m为1时类似?

如果m为4,选a,b,c,d,方案数为1;

如果m为5,a,b,c,d,这四个数肯定还是要选,那么剩下的一个就是e或f,方案数为2;

剩下的以此类推,本蒟蒻便不分别说了。

仔细分析上面的例子,不难发现,在m增加的过程中,我们每次都会选在m较小时所选的数以及剩下的数中最大的,

如果当前有多个最大的,那么就是在求最大的数的种类数中选择x个数(x为m剩下的未选择的次数),这不就是组合数吗?

思路想通了,代码也就不难了,具体在操作上面的步骤时,用递归就可以了。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int m,a[],temp,ans,sum,f[][];
string s;
bool cmp(int x,int y)
{
return x>y;
}
void work(int last,int x)
{
int num=;
for(int i=last+;i<=;i++)
{
if(a[i]==) break;
if(a[i]==a[last+]) num++;
else break;
}
if(num>=x)//从num个数中选x个数
{
for(int i=;i<=num;i++)
for(int j=;j<=i;j++) f[i][j]=f[i-][j]+f[i-][j-];
cout<<f[num][x];
}
else work(last+num,x-num);
}
int main()
{
//freopen("course.in","r",stdin);
//freopen("course.out","w",stdout);
cin>>s;
m=read();
for(int i=;i<s.size();i++) a[s[i]-'a'+]++;
sort(a+,a+,cmp);
f[][]=;
for(int i=;i<=;i++)
{
if(a[i]==) break;
else sum++;
if(temp<m)
{
ans+=a[i];
temp++;
}
}
cout<<ans<<" ";
if(m>=sum) cout<<"";
else work(,m);
return ;
//fclose(stdin);
//fclose(stdout);
}

长乐培训Day8的更多相关文章

  1. 长乐培训Day4

    T1 矩阵 题目 [题目描述] 从前有个 n×m 的矩阵,初始时每个位置均为 0.你需要依次执行 q 个操作,每个操作会指定一行或一列,然后将该行或该列的所有元素全部赋为一个相同的值. 输出操作完成后 ...

  2. 长乐培训Day9

    T1 立方数 题目 [题目描述] 作为XX战队的狂热粉丝,MdZzZZ看到了自己心仪的队伍在半决赛落败,顿时心灰意冷.看着自己手中的从黄牛那里抢来的天价总决赛门票,MdZzZZ觉得去鸟巢已经没有意义了 ...

  3. 长乐培训Day7

    T1 删除 题目 [题目描述] 现在,我的手上有 n 个数字,分别是 a1,a2,a3,...,an. 我现在需要删除其中的 k 个数字.当然我不希望随随便便删除,我希望删除 k 数字之后,剩下的 n ...

  4. 长乐培训Day6

    T1 数列 题目 [题目描述] [输入格式] [输出格式] [输入样例] [输出样例] [数据规模] 如上所述. 解析 身为T1,居然比T4还难......让我怎么办......以下为巨佬题解: 我猜 ...

  5. 长乐培训Day5

    T1 圆圈舞蹈 题目 [题目描述] 熊大妈的奶牛在时针的带领下,围成了一个圈跳舞.由于没有严格的教育,奶牛们之间的间隔不一致. 奶牛想知道两只最远的奶牛到底隔了多远.奶牛A到B的距离为A顺时针走和逆时 ...

  6. 长乐培训Day3

    T1 奶牛晒衣服 题目 [题目描述] 在熊大妈英明的带领下,时针和他的同伴生下了许多牛宝宝.熊大妈决定给每个宝宝都穿上可爱的婴儿装.于是,为牛宝宝洗晒衣服就成了很不爽的事情. 圣人王担负起了这个重任. ...

  7. 长乐培训Day2

    T1 足球联赛 题目 [题目描述] 巴蜀中学新一季的足球联赛开幕了.足球联赛有n只球队参赛,每赛季,每只球队要与其他球队各赛两场,主客各一场,赢一场得3分,输一场不得分,平局两只队伍各得一分. 英勇无 ...

  8. 长乐培训Day1

    T1 魔法照片 题目 [题目描述] 如果你看过<哈利·波特>,你就会知道魔法世界里的照片是很神奇的.也许是因为小魔法师佳佳长的太帅,很多人都找他要那种神奇的魔法照片, 而且还都要佳佳和他的 ...

  9. 长乐国庆集训Day5

    T1 方阵 题目 [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑是有一定规律的.兵马俑阵总共有n ...

随机推荐

  1. 常用spaceclaim脚本(三)

    拉伸曲线 ptList=List[Point]() #定义一个点的列表 ptList.Add(Point.Create(MM(11),MM(-14),MM(0))) #创建点,并放入列表当中 ptLi ...

  2. 数据结构Java版之堆&堆排序(九)

    堆分为大顶堆,和小顶堆. 什么是堆? 堆可以看成是一棵二叉树,二叉树的元素是一个数组不断的从左到右轮训放置.如果是大顶堆,则大的数放上面一层,小的数放下面一层.上一层的数,一定大于下一层的数.小顶堆则 ...

  3. POJ1177和POJ1389 。。。

    POJ 1177 Picture 经典线段树+离散化+扫描线 POJ 1177 Picture (线段树+离散化+扫描线) 详解 线段树(segment tree) http://www.java3z ...

  4. Mitmproxy的mimdump mimproxy mitmweb命令行性能对比

    引用官方的原话如下 Very cool test - thanks for sharing!

  5. QT文本转语音模块(TTS)QTextToSpeech

    QTextToSpeech是QT5.8以上的文本转语音模块. 使用方法: 在.pro工程文件中添加“QT += texttospeech”. 添加头文件 #include <QTextToSpe ...

  6. vue-router 使用query传参跳转了两次(首次带参数,跳转到了不带参数)

    问题: 在做项目的过程中,使用query传参数,发现跳转过程中第一次有参数,但是路由马上又跳转了一次,然后 ?和它之后的参数都不见了 问题分析: 因为路由加载了两次 解决办法: ·1. 找到总的 la ...

  7. android studio: 快捷键生成getter/setter方法时自动加m的问题

    平时使用Android Studio 在写实体类的时候,习惯给实体类的成员变量前面加上一个"m" 修饰符表示这是一个成员变量,这也是搞java的一种约定俗成的写法,本来这是没有问题 ...

  8. flutter 中的搜索条实现

    import 'package:flutter/material.dart'; import 'package:flutter_app/SearchBarDemo.dart'; void main() ...

  9. flutter Radio单选框

    单选框,允许用户从一组中选择一个选项. import 'package:flutter/material.dart'; class RadioDemo extends StatefulWidget { ...

  10. Vscode 调试 Flutter 项目

    1.Vscode 中打开 flutter 项目进行开发 2.运行 Flutter 项目 flutter run r 键:点击后热加载,也就算是重新加载吧. p 键:显示网格,这个可以很好的掌握布局情况 ...