乌鸦嘴如我......果然考差了,直接原因是第二题审错题,当然,深层原因绝不会这么简单。不知道自己花在解题报告上的时间是否有意义,毕竟这些时间本可以改好几道题出来,的确要反思一下。
考试分析:
1.做题习惯不好,不能只观察数据,要结合题给其他条件,站在逻辑的高度。这次审错题个人觉得很经典:把特殊的树当成了链来做,这显然是没有顾全大局的,说明在思考时未能抹去之前错误的认识,完全没有思考解题方法的正确性,还是太急了,要学会反向思考;
2.实现代码太慢,完全没有时间思考第三道题,本来按照思路应该很容易发现动规比深搜快很多的,但却担心来不及写放弃了,要多刷题;
3.花在废话上时间太多,写结题报告显然比调程序简单一点,所以我会花大量的时间来写解题报告,本来总结归纳也是很有用的,但是现在时间不够,找到弱点也没时间落实,不如跟好老师的步伐,尤其是在解题报告里废话少一点;
题目分析:
一.生活大爆炸版石头剪刀布
题意:NCAC题;
题目分析:技巧关键词:取余,对称,直接加分;
代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int n,na,nb,a[205],b[205],stua,stub;
int ovo[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};
int main()
{
freopen("rps.in","r",stdin);
freopen("rps.out","w",stdout);
scanf("%d %d %d",&n,&na,&nb);
for(int i=0;i<=na-1;i++)
scanf("%d",&a[i]);
for(int j=0;j<=nb-1;j++)
scanf("%d",&b[j]);
for(int i=0;i<=n-1;i++)
{
stua+=ovo[a[i%na]][b[i%nb]];
stub+=ovo[b[i%nb]][a[i%na]];
}
printf("%d %d",stua,stub);
return 0;
}
二.联合权值
题意:隔一点的树:n 200 000 w 10 000;
题目分析:
根据题意很容易发现任意两点仅一条路径,发现这条性质以后把图画出来会发现,每次求的就是任意两个子节点的乘积,(树)(仅一个前驱)然后好笑的事情发生了:我把图一画——链嘛,然后编了很久,自以为拿了一百,结果......呵呵(手动微笑)所以拿到题目以后先自己画一个图,再分析样例,并且自己的图一定要是最具一般性的!再想计算时的简化(比如直接找儿子),当然大神提供的一个式子为100%提供了可能,不太好打,可以看程序理解。顺便,longlong运算要比int慢很多,写这种多过一组是一组的程序,一定要能简化的地方都简化!;
(链的愚蠢程序)
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> using namespace std; const int MAXN=200005,m=10007; int sta[MAXN],fin[MAXN],n,w[MAXN],used[MAXN],inf[MAXN][2],flg,maxn,tot,flg2; struct pie { int rig,lef; }lace[MAXN]; void cre(int k,int dot,int las) { used[k]=1; lace[k].lef=las; lace[las].rig=k; int k1=inf[dot][0]+inf[dot][1]-k; int dot1=fin[k1]+sta[k1]-dot; if(k1==0){flg2=dot;lace[k].rig=-1;return;} cre(k1,dot1,k); } void res(int dot,int k,int las) { maxn=max(maxn,w[las]*w[dot]); tot+=(w[las]%m)*(w[dot]%m)%m; tot%=m; if(lace[k].rig==-1)return; int k1=lace[k].rig; int dot1=fin[k1]+sta[k1]-dot; int las1=fin[k]+sta[k]-dot; res(dot1,k1,las1); } void init() { scanf("%d",&n); for(int i=1;i<=n-1;i++) { scanf("%d %d",&sta[i],&fin[i]); if(inf[sta[i]][0])inf[sta[i]][1]=i; else inf[sta[i]][0]=i; if(inf[fin[i]][0])inf[fin[i]][1]=i; else inf[fin[i]][0]=i; } for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<=n;i++) if(!inf[i][1]) {flg=i;break;} int k3=inf[flg][0]; lace[k3].lef=-1; used[k3]=1; int dot=sta[k3]+fin[k3]-flg; int k2=inf[dot][0]+inf[dot][1]-k3; int dot1=fin[k2]+sta[k2]-dot; if(k2==0){ flg2=dot;lace[k3].rig=-1;} else cre(k2,dot1,k3); } int main() { freopen("link.in","r",stdin); freopen("link.out","w",stdout); init(); int k1=inf[flg][0]; int k2=lace[k1].rig; if(k2!=-1) { int dot=fin[k2]+sta[k2]-fin[k1]-sta[k1]+flg; res(dot,k1,flg); } printf("%d %d",maxn,(tot*2)%m); return 0; }
100%的程序
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> using namespace std; const int MAXN=200005,m=10007; int maxn,tot,sta,fin,n,w[MAXN],a[MAXN],b[MAXN],c,d,ans; struct TREE { int f,dot,nex; }lace[2*MAXN]; int main() { freopen("link.in","r",stdin); freopen("link.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n-1;i++) { scanf("%d %d",&sta,&fin); lace[2*i-1].f=sta;lace[2*i-1].dot=fin;lace[2*i-1].nex=a[sta];a[sta]=2*i-1; lace[2*i].f=fin;lace[2*i].dot=sta;lace[2*i].nex=a[fin];a[fin]=2*i; } for(int i=1;i<=n;i++) {scanf("%d",&w[i]);} for(int i=1;i<=n;i++) {int j=a[i];tot=0;c=0;d=0; while(lace[j].nex) { tot++;b[tot]=w[lace[j].dot]; c+=((b[tot]%m)*(b[tot]%m))%m;d+=b[tot]%m; c%=m;d%=m; j=lace[j].nex; } tot++;b[tot]=w[lace[j].dot]; c+=((b[tot]%m)*(b[tot]%m))%m;d+=b[tot]%m; c%=m;d%=m;d*=d;d%=m; sort(b+1,b+tot+1); ans+=(d-c+m)%m;ans%=m; maxn=max(maxn,b[tot]*b[tot-1]); } printf("%d %d",maxn,ans); return 0; }
(这里是不需要除以二的,模后除和除后模因为是int都会出问题,所以只能:1.用逆元;2.观察;)
三.飞扬的小鸟
题意:越过障碍,模拟+动规;(要把每个情况对应时间还是时刻弄清楚)
题目分析:发现x,y可以表示状态后我就打算动规,但想一想x*y时间复杂度好高啊(愚蠢),而且时间又不够就放弃了呵呵(手动微笑),所以实现代码一定要快,为最后一道题留够充足时间,你不会只想要200吧;
这里加了一个优化,直接动规只能70%,但因为你可以从自己推上来,所以你重复计算了很多值,这种重复剪的思维很重要(大神是从背包想出来的,666)