其实这个早就该写了。但是考完之后一直没有时间。考完了之后还是回去上文化课,没有信息课。但是上大周腾出了一节课来分析题目,所以就可以来说说。
这是我今年第一次参加noip普及组的比赛。七年级的时候因为没有进复赛所以不知道是个什么情形(毕竟浙江分数线太高了),总觉得跟小学的比赛应该也差不多。然而真正到了考场才知道不一样,居然在体育馆里放了好多好多的椅子,用的都是笔记本电脑(而且鼠标线有点短,不能扯)。
老师考试前几天说有人考试紧张得很,我还觉得好不真实,没想到自己开始的时候手也在抖。
—————————————————————
其实就是一个简单的字符串模拟。难点就是如何判断空格和换行符。cin读到空格就停止读入,但是有80%数据保证没有空格,所以直接用cin读入字符串可以有80分。我考试的时候用了一个以前从未用过的getchar。考试前老师特意强调了几个读入字符串的函数,对这个的特点比其他几个要熟一些,为了保险,还用了一个奇奇怪怪的while判断。
代码:
#include<bits/stdc++.h>
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<bits/stdc++.h>
using namespace std;
int main()
{
string ch;
int ans=0;
while (cin>>ch)
ans+=ch.size();
cout<<ans<<endl;
return 0;
}
好吧,考场上这道题浪费我大把青春啊。如此简单的第二题,我居然用两个多小时去做它,也是没谁了。在考场上,我这题有三个版本,分类讨论了好久,但是有几个样例死活过不了。后来改啊该,终于把题面上的小样例给过了,但是大数据样例就是过不了。出了考场才知道,那题的样例格式好像还有些问题。后来,这题只有80分啊啊啊啊。跟样例什么的没有关系,思路也没有关系,只是因为忘记考虑计算时爆int。
其实这道题也很简单。就是要枚举每一个可以放置的兵营,然后计算是否最优就可以了。可能我的代码有一些长(或者说繁琐),但是反映了我考场上究竟是怎样思考的。
#include<bits/stdc++.h>
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太难了,我现在还不会。这一题太坑了,好多人写了有后效性的dp。我呢,本来就不会什么dp,随便写了一个奇奇怪怪的程序,无论输入什么都只会输出0,居然也有十分。
今年的第三题比第四题要难,好多人都被坑了,我就是其中一个。
呜呜呜~ 考试的时候,看见是个二叉树,马上觉得我不会,不仅不会,连读入都不会。然后果断放弃。后来发现真的和树的存储和读入没啥关系。
这一题的正解我是不会的,但是暴力我会啊。这一题由于各种奇奇怪怪的特性是可以剪枝的,而且不会超时呢。
代码:
#include<bits/stdc++.h>
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分,已经比我的预估分高许多了。该拿的分都拿到,这就是实力!