牛客练习赛9
2017-12-29 22:04
323 查看
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
珂朵莉想每天都给威廉送礼物,于是她准备了n个自己的本子
她想送最多的天数,使得每天至少送一个本子,但是相邻两天送的本子个数不能相同
珂朵莉最多送几天礼物呢
示例1
思路:
其实就是3个本子(因为要想最多不是1 2就是 2 1),所以判断本子数*2/3即可,若与3求余有余数,则需要再加一
代码:
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
珂朵莉想求123456789101112131415...的第n项
示例1
示例2
思路:
水题。就是模拟一遍分别求出来就可。因为n最大1000,所以数字到400已足够
代码:
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
珂朵莉给你一个有根树,求有多少个子树满足其内部节点编号在值域上连续
一些数在值域上连续的意思即其在值域上构成一个连续的区间
示例1
思路:
通过数状dp来求解,求一个区间数的最大结点和最小节点,然后在和区间内的节点数相比较,如果相等则可以
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX=100010;
struct Edge
{
int next;
int to;
}edge[MAX*2];
int head[MAX];
int vv[MAX]; //找根节点
int vis[MAX];
int maxx[MAX];
int minn[MAX];
int len[MAX];
int N, K;
void addEdge(int u,int v)
{
edge[++K].next = head[u];
edge[K].to=v;
head[u]=K;
}
int dfs(int now)
{
//cout<<"now "<<now<<endl;
if(head[now]==0)
{
len[now]=1;
return 1;
}
vis[now]=1;
int son=1;
for(int i=head[now];i!=0;i=edge[i].next)
{
int next=edge[i].to;
if(vis[next])
continue;
son+=dfs(next);
maxx[now]=max(maxx[now], maxx[next]);
minn[now]=min(minn[now], minn[next]);
//cout<<maxx[now]<<" * "<<minn[now]<<endl;
}
//cout<<endl;
len[now]=son;
return son;
}
int main()
{
int x, y;
while(cin>>N && N)
{
K=0;
memset(vv, 0, sizeof(vv));
memset(vis, 0, sizeof(vis));
memset(edge, 0, sizeof(edge));
memset(head, 0, sizeof(head));
for(int i=1; i<=N; i++)//初始化
{
maxx[i]=minn[i]=i;
}
for(int i=1; i<=N-1; i++)
{
cin>>x>>y;
addEdge(x,y);
vv[y]=1;//gen
}
int now=0;
for(int i=1; i<=N; i++)
{
if(vv[i]==0)
{
now=i;
break;
}
}
dfs(now);
int ans=0;
for(int i=1; i<=N; i++)
{
//cout<<maxx[i]<<" "<<minn[i]<<" "<<len[i]<<endl;
if((maxx[i]-minn[i]+1)==len[i])
ans++;
}
cout<<ans<<endl;
}
return 0;
}
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
珂朵莉想每天都给威廉送礼物,于是她准备了n个自己的本子她想送最多的天数,使得每天至少送一个本子,但是相邻两天送的本子个数不能相同
珂朵莉最多送几天礼物呢
输入描述:
第一行一个整数n
输出描述:
第一行输出一个整数,表示答案
示例1
输入
4
输出
3
说明
第一天送1个本子 第二天送2个本子 第三天送1个本子
备注:
对于100%的数据,有1 <= n <= 1000000000
思路:
其实就是3个本子(因为要想最多不是1 2就是 2 1),所以判断本子数*2/3即可,若与3求余有余数,则需要再加一
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #define ll long long #define maxn 10005 #define inf 1000000001 using namespace std; int main() { ll n; ios::sync_with_stdio(false); cin>>n; ll ans; ans=(int)(n/3.0)*2; //cout<<ans<<"---"<<endl; if(n%3==1||n%3==2) ans++; cout<<ans<<endl; return 0; }
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
珂朵莉想求123456789101112131415...的第n项输入描述:
第一行一个整数n
输出描述:
第一行输出一个整数,表示答案
示例1
输入
3
输出
3
示例2
输入
11
输出
0
说明
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4... 第3个是3 第11个是0
备注:
对于100%的数据,有1 <= n <= 1000
思路:
水题。就是模拟一遍分别求出来就可。因为n最大1000,所以数字到400已足够
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #define ll long long #define maxn 10005 #define inf 1000000001 using namespace std; int a[10005]; int main() { ios::sync_with_stdio(false); int ans=1; int n; for(int i=1;i<=400;i++){ if(i>=1&&i<=9){ a[ans++]=i; } else if(i>=10&&i<=99){ a[ans++]=(i/10)%10; a[ans++]=i%10; } else if(i>=100&&i<=400){ a[ans++]=(i/100)%10; a[ans++]=(i/10)%10; a[ans++]=i%10; } } cin>>n; cout<<a <<endl; return 0; }
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
珂朵莉给你一个有根树,求有多少个子树满足其内部节点编号在值域上连续一些数在值域上连续的意思即其在值域上构成一个连续的区间
输入描述:
第一行有一个整数n,表示树的节点数。 接下来n–1行,每行两个整数x,y,表示存在一条从x到y的有向边。 输入保证是一棵有根树。
输出描述:
输出一个数表示答案
示例1
输入
5 2 3 2 1 2 4 4 5
输出
5
说明
节点1子树中编号为1,值域连续 节点3子树中编号为3,值域连续 节点5子树中编号为5,值域连续 节点4子树中编号为4,5,值域连续 节点2子树中编号为1,2,3,4,5,值域连续
备注:
对于100%的数据,有n <=100000
思路:
通过数状dp来求解,求一个区间数的最大结点和最小节点,然后在和区间内的节点数相比较,如果相等则可以
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX=100010;
struct Edge
{
int next;
int to;
}edge[MAX*2];
int head[MAX];
int vv[MAX]; //找根节点
int vis[MAX];
int maxx[MAX];
int minn[MAX];
int len[MAX];
int N, K;
void addEdge(int u,int v)
{
edge[++K].next = head[u];
edge[K].to=v;
head[u]=K;
}
int dfs(int now)
{
//cout<<"now "<<now<<endl;
if(head[now]==0)
{
len[now]=1;
return 1;
}
vis[now]=1;
int son=1;
for(int i=head[now];i!=0;i=edge[i].next)
{
int next=edge[i].to;
if(vis[next])
continue;
son+=dfs(next);
maxx[now]=max(maxx[now], maxx[next]);
minn[now]=min(minn[now], minn[next]);
//cout<<maxx[now]<<" * "<<minn[now]<<endl;
}
//cout<<endl;
len[now]=son;
return son;
}
int main()
{
int x, y;
while(cin>>N && N)
{
K=0;
memset(vv, 0, sizeof(vv));
memset(vis, 0, sizeof(vis));
memset(edge, 0, sizeof(edge));
memset(head, 0, sizeof(head));
for(int i=1; i<=N; i++)//初始化
{
maxx[i]=minn[i]=i;
}
for(int i=1; i<=N-1; i++)
{
cin>>x>>y;
addEdge(x,y);
vv[y]=1;//gen
}
int now=0;
for(int i=1; i<=N; i++)
{
if(vv[i]==0)
{
now=i;
break;
}
}
dfs(now);
int ans=0;
for(int i=1; i<=N; i++)
{
//cout<<maxx[i]<<" "<<minn[i]<<" "<<len[i]<<endl;
if((maxx[i]-minn[i]+1)==len[i])
ans++;
}
cout<<ans<<endl;
}
return 0;
}
相关文章推荐
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛6 B 点权和 树点权和
- 牛客练习赛3 F 监视任务 每个区间K个 树状数组+贪心
- 牛客练习赛7 购物 DP 初始化问题
- 牛客练习赛7 A B D E
- 牛客练习赛8 A B D E
- nowcoder 牛客练习赛9 B
- 牛客练习赛7 E 题 珂朵莉的数列 【树状数组 + 思维】
- 牛客练习赛3 E - 绝对半径2051
- 牛客练习赛12-A-圆圆
- 牛客练习赛7 B 【排序和优先队列】
- 牛客练习赛13_C-幸运数字Ⅲ(思维)
- 牛客练习赛6 A 【二分】
- 牛客练习赛6 D 世界上最可爱的珂朵莉 贪心
- 牛客练习赛6 B 点权和 树点权和
- 牛客练习赛7 购物 DP 初始化问题
- 牛客练习赛7:B-购物 (dp)
- 牛客练习赛9 E题 珂朵莉的数论题
- 牛客练习赛1 B - 树
- 牛客练习赛13-幸运数字I