链接:https://www.nowcoder.com/acm/contest/136/B
来源:牛客网
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
化而为鸟,其名为鹏。鹏之背,不知其几千里也。
——《庄子·逍遥游》
HtBest的小鲲长大变成了大鹏,大鹏在天际翱翔,看到了一片绵延的山脉,每座山都有自己的高度,大鹏想穿过这片山脉。由于他只能紧贴地面飞行,他想知道他一共要翻越几次大山(上升->平飞->下降,算一次,其中平飞可以没有),初始时,大鹏在山脉的左端。
第一行一个正整数n,表示山脉被分为n段。
第二行有n个正整数ai两两之间用空格分开,ai表示山脉第i段的高度。
一行,包含一个正整数,表示大鹏需要翻越几次大山。
示例1
复制
3
1 2 1
复制
1
大鹏先上升一次,再下降一次,共翻越1次。
示例2
复制
3
3 1 2
复制
0
大鹏先下降一次,再上升一次,共翻越0次。
示例3
复制
3
1 2 3
复制
0
大鹏只需要上升一次,不需要下降,共翻越0次。
对于100%的测试数据:
1 ≤ n ≤ 1000000
1 ≤ ai ≤ 1000000000
数据量较大,注意使用更快的输入输出方式。
很简单的一道签到,暴力找出翻越的次数就行了,可以用一个bool值flag翻滚求
#include
using namespace std;
const int maxn = (int)1e6 + 10;
int a[maxn];
int main()
{
int n;
scanf("%d",&n);
int ans = 0;
for (int i = 0;i < n;i ++)
scanf("%d",&a[i]);
bool flag = 0;
for (int i = 1;i < n;i ++)
{
if (flag && a[i] < a[i - 1])
{
flag = 0;
ans ++;
}
if (a[i] > a[i - 1])
flag = 1;
}
printf("%d\n",ans);
return 0;
}
链接:https://www.nowcoder.com/acm/contest/136/C
来源:牛客网
桃花
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
桃花一簇开无主,可爱深红映浅红。
——《题百叶桃花》
桃花长在桃树上,树的每个节点有一个桃花,调皮的HtBest想摘尽可能多的桃花。HtBest有一个魔法棒,摘到树上任意一条链上的所有桃花,由于HtBest法力有限,只能使用一次魔法棒,请求出Htbest最多可以摘到多少个桃花。
第一行有一个正整数n,表示桃树的节点个数。
接下来n-1行,第i行两个正整数ai,bi ,表示桃树上的节点ai,bi之间有一条边。
第一行一个整数,表示HtBest使用一次魔法棒最多可以摘到多少桃花。
示例1
复制
3
1 2
2 3
复制
3
示例2
复制
3
1 2
1 3
复制
3
示例3
复制
4
1 2
2 3
3 4
复制
4
对于100%的测试数据:
1 ≤ n ≤ 1000000
数据量较大,注意使用更快的输入输出方式。
题意很简单,就是求从一端尾部节点到别的端点经过的最多的节点数量,假设每个父节点与其子节点的距离都为1,那么我们求出树的直径再+1不就行了,牛客的评测机真的有毒,提交第一遍TLE,第二遍相同的代码就过了(900+ms),不管我就这样写了
#include
using namespace std;
const int maxn = (int)1e6 + 10;
vector > G[maxn];
int dis[maxn],ans;
bool vis[maxn];
int bfs(int x)
{
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
queue que;
que.push(x);
vis[x] = 1;
int point = 0;
while (!que.empty())
{
int p = que.front();
que.pop();
if (dis[p] > ans)
{
ans = dis[p];
point = p;
}
pair t;
for (int i = 0;i < G[p].size();i ++)
{
t = G[p][i];
if (vis[t.first] == 0)
{
vis[t.first] = 1;
dis[t.first] = dis[p] + t.second;
que.push(t.first);
}
}
}
return point;
}
int main()
{
int n;
scanf("%d",&n);
int u,v;
for (int i = 0;i < n - 1;i ++)
{
scanf("%d %d",&u,&v);
G[u].push_back(make_pair(v,1));
G[v].push_back(make_pair(u,1));
}
ans = 0;
int p = bfs(1);
ans = 0;
bfs(p);
printf("%d\n",ans + 1);
return 0;
}
链接:https://www.nowcoder.com/acm/contest/136/D
来源:牛客网
符串丝带
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 65536K,其他语言131072K
64bit IO Format: %lld
WHZ送给了HtBest一个“字符串丝带”,这条丝带由n个小写字母按照一定的顺序排列组成,HtBest收到新礼物后有许多问题,类似“第i个位置的字母在前i个位置中出现了几次?”,HtBest很希望知道答案,于是求助你帮忙解答。
第一行有2个正整数n,m,分别表示丝带长度和问题个数。
第二行,有n个小写字母,第i个表示丝带第i位的小写字母。
接下来有m行,每行一个正整数 ,表示HtBest的一个问题。
共m行,对于每个问题,给出答案。
示例1
复制
3 3
abc
1
2
3
复制
1
1
1
示例2
复制
4 4
abba
1
2
3
4
复制
1
1
2
2
示例3
复制
7 7
yyuahhy
7
6
5
4
3
2
1
复制
3
2
1
1
1
2
1
对于100%的测试数据:
1 ≤ n ≤ 1000000
数据量较大,注意使用更快的输入输出方式。
这题也是一道很简单的签到题,只需要预处理另开一个ch数组存前面每个字母的出现次数,一个num数组存当前位置该字母出现的次数即可
#include
using namespace std;
const int maxn = (int)1e6 + 10;
char s[maxn];
int num[maxn];
int ch[30];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
scanf("%s",s);
memset(ch,0,sizeof(ch));
for(int i = 0;i < n;i ++)
{
ch[s[i] - 'a'] ++;
num[i] = ch[s[i] - 'a'];
}
int p;
for (int i = 0;i < m;i ++)
{
scanf("%d",&p);
printf("%d\n",num[p - 1]);
}
return 0;
}
链接:https://www.nowcoder.com/acm/contest/136/H
来源:牛客网
挖沟
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
胡队长带领HA实验的战士们玩真人CS,真人CS的地图由一些据点组成,现在胡队长已经占领了n个据点,为了方便,将他们编号为1-n,为了隐蔽,胡队长命令战士们在每个据点出挖一个坑,让战士们躲在坑里。由于需要在任意两个点之间传递信息,两个坑之间必须挖出至少一条通路,而挖沟是一件很麻烦的差事,所以胡队长希望挖出数量尽可能少的沟,使得任意两个据点之间有至少一条通路,顺便,尽可能的∑d[i][j]使最小(其中d[i][j]为据点i到j的距离)。
第一行有2个正整数n,m,m表示可供挖的沟数。
接下来m行,每行3个数a,b,v,每行描述一条可供挖的沟,该沟可以使a与b连通,长度为v。
输出一行,一个正整数,表示要使得任意两个据点之间有一条通路,至少需要挖长的沟。(数据保证有解)
示例1
复制
2 2
1 2 1
1 2 3
复制
1
示例2
复制
3 3
1 2 3
2 3 4
1 3 5
复制
7
对于100%的测试数据:
1 ≤ n ≤ 100000
1 ≤ m ≤ 500000
1 ≤ v ≤ 10000
一道很明显的最小生成树,kruscal过的
#include
using namespace std;
const int maxn = (int)5e5 + 10;
const int MAXN = (int)1e5 + 10;
int f[MAXN];
struct node
{
int u,v,cost;
}a[maxn];
bool cmp(node x,node y)
{
return x.cost < y.cost;
}
int find(int x)
{
if (x != f[x])
f[x] = find(f[x]);
return f[x];
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for (int i = 1;i <= n;i ++)
f[i] = i;
for (int i = 0;i < m;i ++)
scanf("%d %d %d",&a[i].u,&a[i].v,&a[i].cost);
sort(a,a + m,cmp);
int ans = 0,cnt = 1;
for (int i = 0;i < m;i ++)
{
if (cnt == n)
break;
int fx = find(a[i].u),fy = find(a[i].v);
if (fx != fy)
{
cnt ++;
ans += a[i].cost;
f[fx] = fy;
}
}
printf("%d\n",ans);
return 0;
}