NOIP2018普及组总结——迟了N个月

其实这个早就该写了。但是考完之后一直没有时间。考完了之后还是回去上文化课,没有信息课。但是上大周腾出了一节课来分析题目,所以就可以来说说。

这是我今年第一次参加noip普及组的比赛。七年级的时候因为没有进复赛所以不知道是个什么情形(毕竟浙江分数线太高了),总觉得跟小学的比赛应该也差不多。然而真正到了考场才知道不一样,居然在体育馆里放了好多好多的椅子,用的都是笔记本电脑(而且鼠标线有点短,不能扯)。
老师考试前几天说有人考试紧张得很,我还觉得好不真实,没想到自己开始的时候手也在抖。

—————————————————————

  • T1 title-标题统计

##题目描述##

其实就是一个简单的字符串模拟。难点就是如何判断空格和换行符。cin读到空格就停止读入,但是有80%数据保证没有空格,所以直接用cin读入字符串可以有80分。我考试的时候用了一个以前从未用过的getchar。考试前老师特意强调了几个读入字符串的函数,对这个的特点比其他几个要熟一些,为了保险,还用了一个奇奇怪怪的while判断。

代码:
#include
using namespace std;
int main()
{
	char ch;
	int ans=0;
	ch=getchar();
	int x=1;
	while (x<=5&&ch!='\n')
	//因为题目中说字符串的长度最大为5,所以我考场上为了防止炸掉,搞了一个判断
	{
		if (ch>='A'&&ch<='Z') ans++;
		if (ch>='a'&&ch<='z') ans++;
		if (ch>='0'&&ch<='9') ans++;
		ch=getchar();
		x++;
	}
	cout<<ans<<endl;
	return 0;
}

但是用while(cin>>…)好像要更短。。。
#include
using namespace std;
int main()
{
	string ch;
	int ans=0;
	while (cin>>ch)
		ans+=ch.size();
	cout<<ans<<endl;
	return 0;
}
  • T2 fight-龙虎斗

题目描述

好吧,考场上这道题浪费我大把青春啊。如此简单的第二题,我居然用两个多小时去做它,也是没谁了。在考场上,我这题有三个版本,分类讨论了好久,但是有几个样例死活过不了。后来改啊该,终于把题面上的小样例给过了,但是大数据样例就是过不了。出了考场才知道,那题的样例格式好像还有些问题。后来,这题只有80分啊啊啊啊。跟样例什么的没有关系,思路也没有关系,只是因为忘记考虑计算时爆int。
NOIP2018普及组总结——迟了N个月_第1张图片
其实这道题也很简单。就是要枚举每一个可以放置的兵营,然后计算是否最优就可以了。可能我的代码有一些长(或者说繁琐),但是反映了我考场上究竟是怎样思考的。

#include
using namespace std;
long long n;
long long m,p1,s1,s2;
long long a[100010];
long long D=0,T=0;
int main()
{
	cin>>n;
	for (int i=1;i<=n;i++)
	  cin>>a[i];
	cin>>m>>p1>>s1>>s2;
	a[p1]+=s1;
	for (int i=1;i<m;i++)
	  D=D+a[i]*(m-i);
	for (int i=m+1;i<=n;i++)
	  T=T+a[i]*(i-m);
	if (abs(D-T)<1)//如果此时双方的气势值的差很小,那么就放在m上就好了
	{
		cout<<m<<endl;
		return 0;
	 }
	if (D>T)
	{
		long long t=T;
		long long d=D;
		long long kk=D-T;
		bool p=0;
		long long l=m;
		for (int i=m+1;i<=n;i++)
		{
			t=T+(i-m)*s2;
			if (abs(D-t)<D-T&&abs(D-t)<kk)
			{
				l=i;
				kk=abs(D-t);
			}
		}
		cout<<l<<endl;
		return 0;
	}
	if (D<T)
	{
		long long t,d;
		long long l=m;
		long long kk=T-D;
		for (int i=1;i<m;i++)
		{
			d=D+(m-i)*s2;
			if (abs(T-d)<T-D&&abs(T-d)<kk)
			{
				kk=abs(T-d);
				l=i;
			}
		}
		cout<<l<<endl;
		return 0;
	}
	return 0;
}
  • T3 摆渡车

T3太难了,我现在还不会。这一题太坑了,好多人写了有后效性的dp。我呢,本来就不会什么dp,随便写了一个奇奇怪怪的程序,无论输入什么都只会输出0,居然也有十分。
今年的第三题比第四题要难,好多人都被坑了,我就是其中一个。

  • 对称二叉树

呜呜呜~ 考试的时候,看见是个二叉树,马上觉得我不会,不仅不会,连读入都不会。然后果断放弃。后来发现真的和树的存储和读入没啥关系。

题目描述

这一题的正解我是不会的,但是暴力我会啊。这一题由于各种奇奇怪怪的特性是可以剪枝的,而且不会超时呢。

代码:

#include
using namespace std;
int n;
int v[1000010],anss[1000010];
int le[1000010],ri[1000010];
void work(int id)
{
    anss[id]=1;
    if (ri[id]!=-1)//右子树 
    {
        work(ri[id]);
        anss[id]+=anss[ri[id]];
    }
    if (le[id]!=-1)//左子树 
    {
        work(le[id]);
        anss[id]+=anss[le[id]]; 
    }
}
bool check(int r,int l)
{
    if (r==-1&&l==-1) return true;//如果该节点的左右孩子都没有,那么就是对称二叉树 
    if (r!=-1&&l!=-1&&v[r]==v[l]&&check(ri[r],le[l])&&check(le[r],ri[l])) return true;
    //如果都有左右孩子,且左右孩子的权值相等 ,且左右子树都是对称二叉树 
    return false;
}
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
      cin>>v[i];
    for (int i=1;i<=n;i++)
      cin>>le[i]>>ri[i];
    work(1);//从第一个节点开始计算每个节点的节点数 
    int ans=0;
    for (int i=1;i<=n;i++)//枚举n个点 
      if (check(ri[i],le[i]))//判断每个点是否符合条件 
        ans=max(ans,anss[i]);//取较大值 
    cout<<ans<<endl;
}

原谅我noip过了n个月才写了这篇博客(而且还有一题没过)。我也很无奈啊。All in all,it was a fantastic experience. 这次比赛锻炼了我的能力,也给了我一些教训。考试要看完题啊,不要忘记开long long啊,正解不会不要把暴力给忘了啊,dp不会贪心也要贪一贪啊……

今年是第一次进noip的复赛,我紧张得连手都抖,但也总算有了结果(虽然该掉的坑都掉了)。190分,已经比我的预估分高许多了。该拿的分都拿到,这就是实力!

你可能感兴趣的:(题解,总结)