A题:
题目大意:按照逆时针顺序给出等边三角形的两个顶点,求另一个顶点。
向量旋转。。。之前做过SGU的一道关于向量旋转的题,在这里用上了。
根据已知两点坐标,将向量逆时针旋转π/3度,即可求得另一顶点坐标。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 160 #define Pi acos(-1.0) typedef double db; struct P { db x,y; }p[N]; P rol(P s,P e,db a,db k) //向量se,逆时针旋转a度后,乘上比例系数k,返回新的终点坐标 { P c; db x=e.x-s.x,y=e.y-s.y; c.x=s.x+k*(x*cos(a)-y*sin(a)); c.y=s.y+k*(x*sin(a)+y*cos(a)); return c; } db dis(P a,P b) {return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));} int main() { int t; scanf("%d",&t); while(t--) { P a,b,c; scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y); c=rol(a,b,Pi/3,1); printf("(%.2lf,%.2lf)\n",c.x,c.y); } return 0; }
F题:
找规律/二进制
题目大意:给出a0到an-1,和一个表达式 (a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*.......*(an-1 * x^(2^(n-1))+1)。给出q,求x^q的系数。
观察表达式,可以发现,给出n,可以构成x^0、x^1、x^2、……、x^(2^n-1)项,并且前面的系数就是将对应的指数化为二进制后,1所对应的系数之乘积。比如x^9的系数,把9化为二进制:1001,则对应的系数为a3*a0.
这样,对于给定的q,若大于2^n-1,则结果为0,否则将二进制位上对应为1的系数相乘即可。
感觉题中的数据有问题。。1<=ai<=100,n<=50,那么系数之乘积不会超过5000。。即使中间结果不取膜,也应该不会溢出。但中间不取膜就WA,取膜就过了。。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<iostream> using namespace std; typedef double db; typedef long long LL; #define mod 2012 int a[105]; int main() { int t,Q,n,i; LL p; cin>>t; while(t--) { cin>>n; for(i=0;i<n;++i) cin>>a[i]; cin>>Q; while(Q--) { cin>>p; LL ans=1; i=0; while(p) { if(i>n-1) {ans=0;break;} if(p&1) ans*=a[i]; ++i; p>>=1; ans%=mod; } printf("%d\n",ans%mod); } } return 0; }
I题:
简单的概率DP求期望。
题目大意:n层的三角形,第一层1个格子、第二层2个,以此类推。
先要从第一层走到最后一层的最左边的那个格子。求移动步数的期望。
已知:
1、若当前格子左边没有格子,则向左下、向右下移动的概率为a、b。a+b=1
2、当前格子下面没有格子了,则向左移动概率为1
3、左边有格子、下面也有格子,则向左下、向右下移动的概率为c、d,向左移动的概率为e。c+d+e=1
分析:
这类求期望的问题,通常都是设出到当前状态到目的地的期望,并从目标状态倒推回初始状态。
设dp[i][j]表示从坐标(i,j)到终点的移动步数期望。
我这里是设起点坐标为(1,1),终点坐标为(n,1)。
那么dp[n][1]=0。
然后可以递推出最后一行的期望。再由最后一行依次往上推即可。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<iostream> using namespace std; typedef double db; db dp[50][50]; int main() { int n,i,j; db a,b,c,d,e; while(cin>>n&&n) { cin>>a>>b>>c>>d>>e; memset(dp,0,sizeof(dp)); for(i=2;i<=n;++i) dp[n][i]=dp[n][i-1]+1; for(i=n-1;i>=1;--i) { dp[i][1]=a*(dp[i+1][1]+1)+b*(dp[i+1][2]+1); for(j=2;j<=i;++j) dp[i][j]=e*(dp[i][j-1]+1)+c*(dp[i+1][j]+1)+d*(dp[i+1][j+1]+1); } printf("%.2lf\n",dp[1][1]); } return 0; }