<>
学弟们来了之后,学姐每天都非常高兴的和学弟一起玩耍。这一天,学姐想出了这样一个游戏,她画了一棵树,树上共有
输入第一行为一个整数
如果学姐能胜利,输出"MengMengDa!",否则输出"So sad..."。没有引号。
1
3 1
1 1
1
MengMengDa!
裸的every-sg,连sg具体值都不用求,有问题的地方大概就是,当sg==0(必败)的时候,下一步会选取的是长度最小的某必胜态势,当sg==1的时候,选取长度最大的某必败态势.(不要加入必胜态势)
#include <iostream> #include <cmath> #include <cstring> using namespace std; #define MAXN 100002 int step[MAXN]; int first[MAXN]; int next[MAXN]; int to[MAXN]; int sg[MAXN]; int mex(int i){ if(first[i]==-1)return sg[i]=0; if(sg[i]!=-1)return sg[i]; int p=first[i]; while(p!=-1){ if(mex(to[p])==0)return sg[i]=1; p=next[p]; } return sg[i]=0; } int edgeindex; void addedge(int from,int _to){ next[edgeindex]=first[from]; first[from]=edgeindex; to[edgeindex]=_to; edgeindex++; } int dfs(int i){ if(first[i]==-1)return step[i]=0; if(step[i]!=-1)return step[i]; int minstatus=0x3ffffff,maxstatus=0; int p=first[i]; while(p!=-1){ if(sg[to[p]]==0){ maxstatus=max(maxstatus,dfs(to[p])+1); } minstatus=min(minstatus,dfs(to[p])+1); p=next[p]; } return step[i]=sg[i]==0?minstatus:maxstatus; } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ memset(sg,-1,sizeof(sg)); memset(first,-1,sizeof(first)); memset(step,-1,sizeof(step)); int n,m; edgeindex=0; cin>>n>>m; int temp; for(int i=2;i<=n;i++){ cin>>temp; addedge(temp,i); } for(int i=n;i>=1;i--)mex(i); for(int i=n;i>=1;i--)dfs(i); int maxstep=0; while(m--){ cin>>temp; maxstep=max(step[temp],maxstep); } if(maxstep&1){ cout<<"MengMengDa!"<<endl; } else cout<<"So sad..."<<endl; } return 0; }
学姐果然萌萌哒
e:
425. 木头人足球赛
时间限制 1000 ms 内存限制 65536 KB题目描述
木头人星的行动速度是地球上乌龟的
1/10 (所以可以忽略移动的速度),可是他们也热爱运动,尤其是足球。 他们的足球规则跟人类的一样,足球场尺寸为标准 105 * 68,两队各 11 名球员参赛。 假设 Mays 队的每个队员都是专业的球员,踢球都特别准。而她们的对手 Luke 队截球的规律是,如果行进的球离自己的距离不超过d ,就可以截球成功。 现在 Mays 队的十号球员拿到了球,如果只允许一次射门,Mays 队能不能进球呢? 足球场在xy 平面内,(0,0)至(105,68)矩形范围内,边缘与x,y 轴平行且不能站人。其中Luke队的球门为(0, 30)-(0, 38),Mays 队的球门为(105,30)-(105, 38)输入格式
第一行为组数
T ,对这T 组数据,每组第一行是Mays队十号球员的坐标x0,y0 ,接下来 11 行为 Luke 队的 1 - 11 号队员的属性xi,yi,di , 其中xi,yi 表示 i 号球员的坐标,di 表示i 号球员截球能力值。 保证所有坐标不重复且都在球场范围内,x,y 为整数,d 为正实数1.0≤d≤3.0 。输出格式
每组数据一行,如果 Mays 队10号队员直接可以射门得分,则输出“Shoot!”;如果10号队员不能成功射门,输出"Poor Mays!".
输入样例
1 104 34 1 24 2.928 48 25 2.605 15 41 1.312 39 42 2.454 3 12 2.080 18 39 1.564 10 36 2.530 97 13 1.589 101 57 1.844 84 39 2.561 0 33 1.831
输出样例
Shoot!
从大尧神那里学到了新姿势,通过3/2pi-angle把需要的角度(pi/2-3pi/3)连续并且取正了,以及直接计算切线与圆心连线的夹角来计算切线角度,这题要是卡高精就完了.卡在"如果截球角度下限超过最大射球角度没有及时退出"上,另外还一直卡在"射了自家球门"上....完全没有思考
#include <iostream> #include <cmath> #include <algorithm> using namespace std; #define inf 0x7fffffff const double eps = 1e-6; const double pi=acos(-1); double calk(int x1,int y1,int x2,int y2){ double b=atan2((y2-y1),(x2-x1)); if(b>eps)b=3*pi/2.0-b; else if(b<-eps)b=-pi/2.0-b; else b=3*pi/2.0; return b; } double caldis(int x1,int y1,int x2,int y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));} void caldk(int x0,int y0,int x1,int y1,double d,double& ans1,double &ans2){ double dis=caldis(x0,y0,x1,y1); double a=asin(d/dis); // cout<<"a"<<a<<endl; double b=calk(x0,y0,x1,y1); // cout<<"b"<<b<<endl; ans1=max(b+a,b-a); ans2=min(b-a,b+a); } int x[12],y[12]; double d[12]; struct foot{ double s, e; }; foot k[11]; bool cmp(foot f1,foot f2){ if(f1.s+eps<f2.s)return true; return false; } int main(){ int t; cin>>t; while(t--){ cin>>x[0]>>y[0]; for(int i=1;i<12;i++){ cin>>x[i]>>y[i]>>d[i]; } bool fl2=false; for(int i=1;i<12;i++){ if(caldis(x[0],y[0],x[i],y[i])<d[i]+eps){ cout<<"Poor Mays\n"<<endl; fl2=true; } if(fl2)break; } if(fl2)continue; double maxk=calk(x[0],y[0],0,38); double mink=calk(x[0],y[0],0,30); for(int i=1;i<12;i++){ caldk(x[0],y[0],x[i],y[i],d[i],k[i-1].e,k[i-1].s); } sort(k,k+11,cmp); //for(int i=0;i<11;i++)cout<<"k"<<i+1<<" "<<k[i].s<<" "<<k[i].e<<endl; double s=mink,e=mink; bool fl=false; for(int i=0;i<11;i++){ if(k[i].s>maxk+eps)break; if(s+eps<k[i].s){ s=k[i].s; if(e+eps<k[i].s){fl=true;break;} } e=max(e,k[i].e); //cout<<"s "<<s<<"e"<<e<<endl; } if(!fl&&e+eps<maxk)fl=true; if(fl)cout<<"Shoot!\n"; else cout<<"Poor Mays!\n"; } return 0; }