博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOIP2018普及组 5.3校模拟
阅读量:5080 次
发布时间:2019-06-12

本文共 4894 字,大约阅读时间需要 16 分钟。

 

 

这还有什么说头吗?饭都不让吃了好吗!!

行。狠。

A. 【NOIP2018普及组】标题统计

 

这个可能就是想考你一个无限输入的语法和ASCII码的运用吗…

#include
#include
using namespace std;int main(){ //freopen("title.in","r",stdin); //freopen("title.out","w",stdout); char Title; int Answer=0; while(~scanf("%c",&Title)){ if(Title>='A'&&Title<='Z'){ Answer++; } else if(Title>='0'&&Title<='9'){ Answer++; } else if(Title>='a'&&Title<='z'){ Answer++; } } printf("%d",Answer); return 0;}

B. 【NOIP2018普及组】龙虎斗

十年OI一场空,不开longlong见祖宗。十年OI一场空,不开longlong见祖宗。十年OI一场空,不开longlong见祖宗。

肥肠简单的差值运算题,计算一下势力值并且计算一下两势力差,然后判断哪边高,把兵给低的那边派过去。具体派哪个地方,暴力枚举即可。最后判断一下,看你枚举了半天有没有刚开始的差值小,如果是初始差值小,输出中立阵营,否则输出你枚举的兵营咯。

#include
#include
#include
using namespace std;long long Line[500000];long long n,p1,s1,s2,m,p2;long long Dragon,Tiger,MinLess,Buding,Index,Yuan;//bool TheSame(long long a,long long b){// if(b>a){// TheSame(b,a);// }// return a-b<0.00001;//}int main(){ //freopen("fight.in","r",stdin); //freopen("fight.out","w",stdout); scanf("%d",&n); //Minless=9999999; p2=99999999; for(int i=1;i<=n;i++){ scanf("%d",&Line[i]); } scanf("%d%d%d%d",&m,&p1,&s1,&s2); Line[p1]+=s1; for(int i=1;i
Yuan){ printf("%d",m);// cout<<"引用自Yuan"; } else{ if(p2==99999999){ printf("%d",m); return 0; } printf("%d",p2);// cout<<"引用自p2"; } return 0;}

但是我没开Long Long呀~(淦)

C. 【NOIP2018普及组】摆渡车

D. 【NOIP2018普及组】对称二叉树

 

 

这个题比较尴尬。我误以为必须是那种左右子节点都存在并且权值相等才算对称,然而并不是。并且我的第一想法是去搭建数组并且通过一番递归计算来还原这棵树,然而,这题的端点极限是10^6,如果用数组来模拟,在最差的情况下(线性向下节点),一定会导致爆炸多的空白数据,从而导致根本没有那么大的数组可以构建这棵树。所以虽然建树模拟写得可以,在建树的同时就已经计算了子节点个数,但依旧没什么卵用。拿了个12分。

 

#include
#include
using namespace std;struct Node{ int Val; int Id; int pos; int childs; bool SamePossible;}Tree[40000000];int n,vi,li,ri,ans,maxer;int Vals[40000000];int child[40000000][3];void BuildTree(Node now){ if(now.pos>=maxer){ maxer=now.pos; } Tree[now.pos].SamePossible=true; if(now.Id==-1){ Tree[(now.pos)/2].childs--; return; } Tree[now.pos].childs+=2; Tree[now.pos].Val=Vals[now.Id]; Tree[now.pos*2].Id=child[now.Id][1]; Tree[now.pos*2].pos=now.pos*2; Tree[now.pos*2+1].Id=child[now.Id][2]; Tree[now.pos*2+1].pos=now.pos*2+1; BuildTree(Tree[now.pos*2]); BuildTree(Tree[now.pos*2+1]); Tree[now.pos].childs+=Tree[now.pos*2].childs+Tree[now.pos*2+1].childs;}bool IsSame(Node now){ if(now.SamePossible==false){ return false; } if(now.Val==0){ int father=now.pos/2; if(Tree[father*2].Val==Tree[father*2+1].Val){ return true; } return false; } if(IsSame(Tree[now.pos*2])&&IsSame(Tree[now.pos*2+1])){ return true; } else{ Tree[now.pos].SamePossible=false; return false; } }int main(){ //freopen("tree.in","r",stdin); //freopen("tree.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&Vals[i]); } Tree[1].Id=1;Tree[1].Val=Vals[1];Tree[1].pos=1;Tree[1].SamePossible=true; for(int i=1;i<=n;i++){ scanf("%d%d",&li,&ri); child[i][1]=li; child[i][2]=ri; } BuildTree(Tree[1]); for(int i=1;i<=maxer+1;i++){ if(IsSame(Tree[i])){ //cout<<"第"<
<<"个节点是对称"<

于是就开始重构,参考了下洛谷的题解,这道题其实不用忙着把树老老实实还原了。看来本来挺简单道题,被想复杂了呢。

#include 
#define ll long long/*代码来自Luo Gu Koakuma已经完全理解并可以重构*/const int maxn = 2000000;using namespace std;ll a[maxn], l[maxn], r[maxn];ll ans, N; /*a数组存节点数值,l[i]表示编号为i的节点的左孩子的编号,r[i]表示编号为i的节点的右孩子的编号*/bool f; //全局变量f判断是否为对称二叉子树inline ll cnt(ll x) //计算以x为根节点的对称二叉子树的节点数 *递归{ ll sum = 0; if(l[x] != -1) sum += cnt(l[x]); if(r[x] != -1) sum += cnt(r[x]); return sum + 1; //别忘了根节点}void work(ll xx,ll yy) //判断对称二叉子树的函数 *递归{ if(xx == -1 && yy == -1)return ; //如果已经到底了,结束 if(xx == -1 || yy == -1 || a[xx] != a[yy]){ f = 0; return ;} //不对称 work(l[xx], r[yy]); work(r[xx], l[yy]); }int main(){ cin >> N;//读入n for (int i = 1 ; i <= N ; ++i) //读入每个节点的值 scanf("%lld", &a[i]); for (int i = 1 ; i <= N ; ++i) //读入每个节点的左右孩子节点编号 scanf("%lld%lld", &l[i], &r[i]); ans = 1; //至少有一个对称(一个节点) for (int i = 1 ; i <= N ; ++i) //枚举对称二叉子树的根节点 if (l[i] != -1 && r[i] != -1 && a[l[i]] == a[r[i]]) //这里可以过滤掉很多不必要的枚举 { f = true; //先默认为是对称二叉子树 work(l[i],r[i]); //开始递归判断 if (f == true) ans = max(ans, cnt(i)); //如果是对称二叉子树就可以计算节点取最大值了 } printf("%lld\n", ans); return 0; }

而关于这一句

 work(l[xx],r[yy]); work(r[xx],l[yy]); 

其实就是我犯得错误,它是两边对称的…呵,万恶之源。

 

转载于:https://www.cnblogs.com/Uninstalllingyi/p/10805983.html

你可能感兴趣的文章
oracle 报错ORA-12514: TNS:listener does not currently know of service requested in connec
查看>>
python3 生成器与迭代器
查看>>
java编写提升性能的代码
查看>>
Abstract Factory Pattern
查看>>
list 容器 排序函数.xml
查看>>
《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇03:暂停游戏》
查看>>
CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
查看>>
windows下编译FreeSwitch
查看>>
git .gitignore 文件不起作用
查看>>
Alan Turing的纪录片观后感
查看>>
c#自定义控件中的事件处理
查看>>
django Models 常用的字段和参数
查看>>
IOS--沙盒机制
查看>>
使用 JointCode.Shuttle 访问任意 AppDomain 的服务
查看>>
sqlite的坑
查看>>
digitalocean --- How To Install Apache Tomcat 8 on Ubuntu 16.04
查看>>
【题解】[P4178 Tree]
查看>>
Jquery ui widget开发
查看>>
关于indexOf的使用
查看>>
英语单词
查看>>