NOIP2017SummerTraining0717
个人感受:自己水平是真的差劲,和他们不是一个档次的,第二题,如果不是陈载元暴力过了,我也不会那么早去A了第二题,第一题真的是无语,以前做到过,还想到了每个对应值a[i]-i,但是没想出来,真的是
可惜,这套题的话前两题都比提高组的要水,但这样下去,别说省选,TG一等都难拿。
改造二叉树
时间限制: 1 Sec 内存限制: 256 MB
提交: 365 解决:
95
[提交][状态][讨论版]
题目描述
小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树。通常子结点被称作“左孩子”和“右孩子”。二叉树被用作二叉搜索树和二叉堆。随后他又和他人讨论起了二叉搜索树。
什么是二叉搜索树呢?二叉搜索树首先是一棵二叉树。设key[p]表示结点p上的数值。对于其中的每个结点p,若其存在左孩子lch,则key[p]>key[lch];若其存在右孩子rch,则key[p]<key[rch];注意,本题中的二叉搜索树应满足对于所有结点,其左子树中的key小于当前结点的key,其右子树中的key大于当前结点的key。
小Y与他人讨论的内容则是,现在给定一棵二叉树,可以任意修改结点的数值。修改一个结点的数值算作一次修改,且这个结点不能再被修改。若要将其变成一棵二叉搜索树,且任意时刻结点的数值必须是整数(可以是负整数或0),所要的最少修改次数。
相信这一定难不倒你!请帮助小Y解决这个问题吧。
输入
第一行一个正整数n表示二叉树结点数。结点从1~n进行编号。
第二行n个正整数用空格分隔开,第i个数ai表示结点i的原始数值。
此后n - 1行每行两个非负整数fa, ch,第i + 2行描述结点i + 1的父亲编号fa,以及父子关系ch,(ch = 0 表示i + 1为左儿子,ch = 1表示i + 1为右儿子)。
结点1一定是二叉树的根。
输出
仅一行包含一个整数,表示最少的修改次数。
样例输入
3 2 2 2 1 0 1 1
样例输出
2
提示
【数据范围】
20 % :n <= 10 , ai <= 100.
40 % :n <= 100 , ai <= 200
60 % :n <= 2000 .
100 % :n <= 10 ^ 5 , ai < 2 ^ 31.
这道题做完后我发现自己是真的菜,推了10多分钟已经推出了二叉树的中序遍历,然后真的就讲问题转化为了将一个序列改变最小的数,使其满足各个数不同且单调递增,这个思维想下去就联想到了LIS
然后想了许久,到了13:50,陈载元A了第二题,说是什么暴力,然后我也去打了一个,花了半小时左右就A了,然后第三题去打了个暴力,这时14:45左右,然后又开始打第一题,真的恶心,想了,暴力,
DP,二分,妈的一个都套不进去,绝望了,最后半小时,。。。。。
最后题解就是先顺着我的思路下去,然后就是求一遍a[i]-i后求一次LIS(这个我还真想到了,但是我求的是最长上升序列,不是最长不下降序列),无语了。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
;
int n,cnt;
int a[NN],vis[NN],pre[NN];
struct node
{
int left,right;
;}
}tree[NN];
void dfs(int num)
{
) dfs(tree[num].left);
vis[++cnt]=a[num];
) dfs(tree[num].right);
}
void mid_find(int x)
{
,r=cnt;
while (l<r)
{
mid=(l+r)/;
;
else r=mid;
}
if (pre[l]>x) pre[l]=x;
else pre[++cnt]=x;
}
int main()
{
scanf("%d",&n);
;i<=n;i++)
{
scanf("%d",&a[i]);
tree[i].init();
}
int x,y;
;i<=n;i++)
{
scanf("%d%d",&x,&y);
) tree[x].left=i;
else tree[x].right=i;
}
cnt=;
memset(vis,,sizeof(vis));
memset(pre,,sizeof(pre));
dfs();
;i<=n;i++)
vis[i]-=i;
cnt=,pre[cnt]=vis[];
;i<=n;i++)
mid_find(vis[i]);
cout<<n-cnt<<endl;
}
问题 B: 数字对
时间限制: 2 Sec 内存限制: 256 MB
提交: 307 解决:
101
[提交][状态][讨论版]
题目描述
小H是个善于思考的学生,现在她又在思考一个有关序列的问题。
她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。
这个特殊区间满足,存在一个k(L <= k <= R),并且对于任意的i(L <= i <= R),ai都能被ak整除。这样的一个特殊区间 [L, R]价值为R - L。
小H想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。
输入
第一行,一个整数n.
第二行,n个整数,代表ai.
输出
第一行两个整数,num和val,表示价值最大的特殊区间的个数以及最大价值。
第二行num个整数,按升序输出每个价值最大的特殊区间的L.
样例输入
5 4 6 9 3 6
样例输出
1 3 2
提示
【样例输入2】
5
2 3 5 7 11
【样例输出2】
5 0
1 2 3 4 5
【数据范围】
30%: 1 <= n <= 30 , 1 <= ai <= 32.
60%: 1 <= n <= 3000 , 1 <= ai <= 1024.
80%: 1 <= n <= 300000 , 1 <= ai <= 1048576.
100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.
这题思维主要来自于陈载元,他说暴力过了,然后我就打了个n^2,但我仔细想过,绝对不会到N^2的,因为枚举每个点,从前往后扫和从后往前扫时如果不是最小的数怕几个就扫完了,而且还要考虑能否整除的关系,所以还是可以行的通的。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
;
int n;
int a[NN];
bool cmp(int x,int y)
{
return x<y;
}
int main()
{
scanf("%d",&n);
;i<=n;i++)
scanf("%d",&a[i]);
int maxlen=-NN;
,b[NN];
c[]=-;
;i<=n;i++)
{
,k=i+;
) {) break;j--;}
) break;k++;}
j++,k--;
k=k-j;
if (k>maxlen)
{
cnt=;
maxlen=k;
c[++cnt]=j;
}
else if (k==maxlen) c[++cnt]=j;
}
sort(c+,c+cnt+,cmp);
;
;i<=cnt;i++)
]) b[++num]=c[i];
cout<<num<<' '<<maxlen<<endl;
;i<num;i++)
cout<<b[i]<<' ';
cout<<b[num]<<endl;
}
交换
时间限制: 1 Sec 内存限制: 256 MB
提交: 167 解决: 47
[提交][状态][讨论版]
题目描述
给定一个{0, 1, 2, 3, … , n - 1}的排列 p。一个{0, 1, 2 , … , n - 2}的排列q被认为是优美的排列,当且仅当q满足下列条件:
对排列s = {0, 1, 2, 3, ..., n - 1}进行n – 1次交换。
<!--[if
!supportLists]-->1.
<!--[endif]-->交换s[q0],s[q0 + 1]
<!--[if
!supportLists]-->2.
<!--[endif]-->交换s[q1],s[q1 + 1]
…
最后能使得排列s = p.
问有多少个优美的排列,答案对10^9+7取模。
输入
第一行一个正整数n.
第二行n个整数代表排列p.
输出
仅一行表示答案。
样例输入
3 1 2 0
样例输出
1
提示
【样例解释】
q = {0,1} {0,1,2} ->{1,0,2} -> {1, 2, 0}
q = {1,0} {0,1,2} ->{0,2,1} -> {2, 0, 1}
【数据范围】
30%: n <= 10
100%: n <= 50
这道题考试的时候没怎么去想,因为****的第一题关系,然后第三题随便 暴力了一下,还编译错误。听力班长wsj大神的讲解后,算是大概理解了,实现了一下,也是一次AC
题意就是给你一个序列,问有多少种完美序列可以从原序列(0,1,2,n-1)推过来,完美序列是什么还和它的次序,有关,,自己理解为主。
然后就可以发现交换a[i]和a[i+1]后i前面和i后面就断绝联系了,前面的无法到后面,后面的无法到前面,然后就可以进行DP如果可以交换,就进行一次dfs,因为完美序列和次序有关,
然后就是累加,记忆化搜索就可以了,n^4 随便过这里有C数组的预处理,好好学学才行。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
,MOD=1e9+;
int n;
int p[NN];
};
long long dfs(int l,int r)
{
;
) return f[l][r];
;;}
f[l][r]=;
for (int i=l;i<r;i++)
{
];
int right=p[i];
for (int j=l;j<i;j++)left=max(p[j],left);
;j<=r;j++)right=min(right,p[j]);
if (left<right)
{
swap(p[i],p[i+]);
f[l][r]=(f[l][r]+dfs(l,i)*dfs(i+,r)%MOD*c[r-l-][i-l])%MOD;
swap(p[i],p[i+]);
}
}
return f[l][r];
}
int main()
{
scanf("%d",&n);
;i<=n;i++)
scanf("%d",&p[i]);
;i<=n;++i)
{
c[i][]=;
;j<=i;++j)
c[i][j]=(c[i-][j-]+c[i-][j])%MOD;
}
memset(f,-,sizeof(f));
,n);
printf("%d",ans);
}
NOIP2017SummerTraining0717的更多相关文章
随机推荐
- MySQL整数类型说明 int(5) vs int(7)
今天突然发现, mysql 中int(1)和tinyint(1)中的1只是指定显示长度,并不表示存储长度,只有字段指定zerofill时有用.位数限制基本没有意义. int(5) 这里的5表示的是 最 ...
- [C]成员运算符"."和间接成员运算符"->"浅析
成员运算符: . 成员运算符一般和结构或者联合名一起使用,指定结构或者联合中的某个成员. 举个栗子: 如果Ronz是一个结构的名称,linux是这个结构模板指定的一个成员名. struct{ //匿名 ...
- sublime编辑器代码背景刺眼怎么修改?
有些人觉得如上图大括号刺眼,怎么把它改得不那么刺眼呢? [第一步]打开Bracket Hightlighter插件的用户配置文件: 然后按ctrl+G跳转到第330行, 如图位置改为"sty ...
- 团队作业8——第二次项目冲刺(Beta阶段)--5.23 third day
团队作业8--第二次项目冲刺(Beta阶段)--5.23 third day Day three: 会议照片 项目进展 今天是beta冲刺的第三天,组长回到了队伍当中,正式开始改进alpha中存在的功 ...
- 团队作业8——第二次项目冲刺(Beta阶段)Day4--5.21
展开圆桌式会议: 会议内容:1.团队成员对昨天任务完成情况做一个简单交流,并对昨天工作中存在的问题提出集中讨论解决:2.按照昨天的昨天工作分配表做具体的任务分配:3.简单讨论明天的任务分配每个人的工作 ...
- 201521123048《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1.clone方法 1.1 Object对 ...
- 201521123073 《Java程序设计》第6周学习总结
1. 本章学习总结 2. 书面作业 1.clone方法 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 1.2 自己设计类时,一 ...
- 201521123079《java程序设计》第3周学习总结
1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...
- 201521123021第二周Java学习总结
1.本章学习总结 ①初步掌握了Java程序简单的输入和输出. ②回顾了运算符和表达式的使用. ③在数据类型的学习的中,要注意各类型的取值范围,特别是byte型范围很小,若为128即溢出. ④在Java ...
- 快递鸟顺丰物流api接口对接多种方法整理
目前很多自营电商平台.ERP系统.仓储系统.快递柜企业,对物流模块数据需求还是比较旺盛的.之前有介绍过简单的接口对接方法,这次给大家整理介绍两种快递数据的获取方法. 接口秘钥可以向顺丰公司申请,或者一 ...