纪中集训 Day29&Day30
T1:
递归
T2:
全部转小写
用find函数
T3:
贪心
T4:
floyed找两点之间最短路
然后根据序列加相邻两点之间的路径长度
全部都是大暴力
怪我太菜了
T1
题目:
F
J
FJ
FJ的奶牛喜欢探索农场周围的地形。一开始,所有
N
N
N(1<=
N
N
N<=1,000,000,000)只奶牛一起出发,但当碰到路口时,这一群牛可能会分成两部分(不能为空),每一部分都继续前进,当碰到另一个路口时,再分成两部分,如此反复下去。假设路上到处都是新的岔口,计算最终被分成多少支队伍。
输入:
第1行: 两个用空格隔开的整数:
N
N
N,
K
K
K,其中
K
K
K表示分裂时两个队伍的奶牛数目差。
输出:
1行: 输出一个整数表示最终的队伍数。
样例:
input
6 2
output
3
提示:
输入说明:有6只奶牛,分裂时两个小组的奶牛差为2.
输出说明:最终有3支队伍分别为
6
/ \
2 4
/
1 3
数量分别为2,1,3。
解题思路:
递归分解成两队
不能分就答案+1
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,ans;
void dfs(int x)
{
if ((x-m)%2==0&&x-m>0)
{
dfs((x-m)/2);
dfs((x-m)/2+m);
}
else ans++;
}
int main()
{
freopen("search.in","r",stdin);
freopen("search.out","w",stdout);
scanf("%d%d",&n,&m);
dfs(n);
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
T2
题目:
F
J
FJ
FJ想计算他的
N
N
N(1<=
N
N
N<=1000)只奶牛的名字的好听度,每个奶牛的名字是一个长度不超过1000的英文字母串。他创建了一个好名字的集合,数量为
M
M
M(1<=
M
M
M<=100),每个好名字的长度不超过30,奶牛的名字中每包含一个好名字(“包含”不一定要求连续),那么它的好听度就加1。所有的名字都不区分大小写,如名字“
B
e
s
s
i
e
Bessie
Bessie”包含“
B
e
Be
Be”、“
s
I
sI
sI”、“
E
E
EE
EE”、“
E
s
Es
Es”,但是不包含“
e
B
eB
eB”。
现在请你帮
F
J
FJ
FJ计算每个奶牛名字的好听度。
输入:
第1行: 2个用空格隔开的整数
N
N
N和
M
M
M;
第2…
N
N
N+1行: 第i+1行为第
i
i
i个奶牛的名字;
第N+2…
N
N
N+
M
M
M+1行:第
N
N
N+
i
i
i+1行为第i个好名字。
输出:
第1…
N
N
N行:第i个数为第i头奶牛名字的好听度。
样例:
input
5 3
Bessie
Jonathan
Montgomery
Alicia
Angola
se
nGo
Ont
output
1
1
2
0
1
提示:
输入说明:
F
J
FJ
FJ有5头奶牛,名字依次为"
B
e
s
s
i
e
Bessie
Bessie", “
J
o
n
a
t
h
a
n
Jonathan
Jonathan”,"
M
o
n
t
g
o
m
e
r
y
Montgomery
Montgomery",
A
l
i
c
i
a
Alicia
Alicia“和”
A
n
g
o
l
a
Angola
Angola",有3个好名字分别为"
s
e
se
se","
n
G
o
nGo
nGo"和 “
O
n
t
Ont
Ont”.
输出说明: “ B e s s i e Bessie Bessie” 包含 “se”, “Jonathan"包含"Ont”, “ M o n t g o m e r y Montgomery Montgomery“包含 “ n G o nGo nGo” 、” O n t Ont Ont”,” A l i c i a Alicia Alicia“不包含任何好名字," A n g o l a Angola Angola“包含” n G o nGo nGo".
解题思路:
输入名字以及好名字
将它们全部转换为小写
然后开始枚举
对每个名字都和好名字匹配
我用了find,具体用法看程序
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,t,w,y,l,len[1200];
string s[1200],c[1200];
char x;
int main()
{
freopen("word.in","r",stdin);
freopen("word.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
t=0;
cin>>s[i];
l=s[i].length();
for (int j=0;j<l;j++)
if (s[i][j]<97) s[i][j]+=32; //转小写
}
for (int i=1;i<=m;i++)
{
t=0;
cin>>c[i];
len[i]=c[i].length(); //存长度
for (int j=0;j<len[i];j++)
if (c[i][j]<97) c[i][j]+=32; //转小写
}
for (int i=1;i<=n;i++)
{
w=0; //答案
for (int j=1;j<=m;j++)
{
y=-1; //初始查找位置
for (int k=0;k<len[j];k++)
{
y=s[i].find(c[j][k],y+1); //分开一个一个字符找,从上一个字符所在位置的下一位开始
if (y==-1) //没有找到推出
break;
}
if (y!=-1) //完全匹配,答案+1
w++;
}
cout<<w<<endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}
T3
题目:
高速公路上有
N
N
N(1<=
N
N
N<=50,000)只奶牛,编号为1…
N
N
N,每头牛都开着自己的车,第
i
i
i头牛的车速为
S
S
S
i
i
i(1<=
S
S
S
i
i
i<=1,000,000)
k
m
km
km/
h
h
h,告诉公路上一共有
M
M
M个车道(1<=
M
M
M<=
N
N
N)。为了安全起见,每头牛都遵循以下原则:同车道前面有
x
x
x头牛,牛的车速就会降低
D
D
D
X
X
X(0<=
D
D
D<=5,000)
K
M
KM
KM/
h
h
h,当然不会降到0以下,所以车速应该
m
a
x
max
max(
S
S
S_
i
i
i-
D
D
D
X
X
X,0)。由于车距很大,所以即使后面的车比前面的车快,你也不用担心会发生碰撞。
高速公路上有一个最低限速
L
L
L(1<=
L
L
L<=1,000,000),凡是低于该速度的车不允许上高速,现在请你来计算一共可以多少辆车在高速公路上行驶。
输入:
第1行:4个空格隔开的整数
N
N
N,
M
M
M,
D
D
D,
L
L
L;
第2…
N
N
N+1行: 第
i
i
i+1行描述第i头牛的起初车速。
输出:
一行:输出一个整数表示最多可以在高速上行驶的牛车数量。
样例:
input
3 1 1 5
5
7
5
output
2
解题思路:
排序+贪心
用数组存当前路上牛的只数
枚举能加进哪条路
代码:
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,d,l,p,k,ans;
int a[50010],b[50010];
int main()
{
freopen("cowcar.in","r",stdin);
freopen("cowcar.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&d,&l);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
k=0;
for (int i=1;i<=n;i++)
{
p=0;
for (int j=1;j<=k;j++)
if (max(a[i]-d*b[j],0)>=l)
{
b[j]++; //牛的只数+1
p=1; //标记,已加入
break;
}
if (p==0&&k<m&&a[i]>=l) //不能加进当前有的路,速度>限速新建一条路
b[++k]=1;
}
for (int i=1;i<=k;i++)
ans+=b[i];
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
T4
题目:
F
J
FJ
FJ在一条船上,海上有
N
N
N(1<=
N
N
N<=100)个岛,编号为1…
N
N
N,现在他的任务是按照一个给定的访问次序
A
A
A_1,4A
2
,
…
.
_2,….
2,….AKaTeX parse error: Expected group after '_' at position 1: _̲M
去
探
索
这
去探索这
去探索这M
(
2
<
=
(2<=
(2<=M
<
=
10
,
000
)
个
岛
屿
,
已
经
知
道
任
意
两
个
岛
屿
之
间
的
危
险
系
数
,
让
你
找
出
一
个
探
索
序
列
,
只
需
满
足
你
的
探
索
序
列
包
含
给
定
的
<=10,000)个岛屿,已经知道任意两个岛屿之间的危险系数,让你找出一个探索序列,只需满足你的探索序列包含给定的
<=10,000)个岛屿,已经知道任意两个岛屿之间的危险系数,让你找出一个探索序列,只需满足你的探索序列包含给定的A
1
.
.
_1..
1..AKaTeX parse error: Expected group after '_' at position 1: _̲M$这个序列就可以(不一定要连续),使得总的危险系数最小。
输入:
第1行:两个数,
N
N
N 和
M
M
M
第 2…
M
M
M+1行:第
i
i
i+1行表示给定的序列中第i个岛屿A_i
第
M
M
M+2…
N
N
N+
M
M
M+1行:每行
N
N
N个整数,表示岛屿之间的危险系数,左对角线上一定是0。
输出:
输出满足要求的最小危险系数
样例:
input
3 4
1
2
1
3
0 5 1
5 0 2
1 2 0
output
7
提示:
我们可以按照1,3,2,3,1,3的顺序去探索,满足了规定了序列是该序列的字序列,危险系数为(1,3)+(3,2)+(2,3)+(3,1)+(1,3)=7。
解题思路:
f
l
o
y
e
d
floyed
floyed求最短路
然后累加两两相邻的点之间的路径长度
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int d[120][120],a[10010];
int n,m,ans;
int main()
{
freopen("danger.in","r",stdin);
freopen("danger.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&d[i][j]);
for (int k=1;k<=n;k++) //floyed
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (i!=j&&i!=k&&j!=k&&d[i][j]>d[i][k]+d[k][j])
d[i][j]=d[i][k]+d[k][j];
for (int i=1;i<m;i++)
ans+=d[a[i]][a[i+1]]; //累加路径长度
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}