表示这场网络赛好伤,1004因为看错题没有AC,最后导致只出三题。。被踩烂了QAQ
1002:题意是给出若干个旋转中心和旋转角度,旋转整个平面,让你把他们合并成一个旋转,输出旋转的中心A和角度P。
当时比赛的时候队友敲几何过的,我当时敲迭代,然后看他已经过了就没敲,赛后敲了一下也AC了。
几何的方法其实还是比较好想的,这里就不说了,我解释一下迭代的做法。
设平面上一个点坐标为(x,y),然后对每次旋转操作后的坐标表示成(A1*x+A2*y+A3,B1*x+B2*y+B3)的形式,将最后得到的结果和转移公式比较,就可以得到角度和坐标的值了。详情请见代码吧
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define LL __int64
int main()
{
int T,n;
double x,y,p;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
double A1=1.0,A2=0.0,A3=0.0;
double B1=0.0,B2=1.0,B3=0.0;
while(n--)
{
scanf("%lf%lf%lf",&x,&y,&p);
double a1=0.0,a2=0.0,a3=0.0;
double b1=0.0,b2=0.0,b3=0.0;
a1=cos(p)*A1-sin(p)*B1;
a2=cos(p)*A2-sin(p)*B2;
a3=cos(p)*A3-sin(p)*B3+x-x*cos(p)+y*sin(p);
b1=sin(p)*A1+cos(p)*B1;
b2=sin(p)*A2+cos(p)*B2;
b3=sin(p)*A3+cos(p)*B3+y-x*sin(p)-y*cos(p);
A1=a1;A2=a2;A3=a3;
B1=b1;B2=b2;B3=b3;
}
double pop=sqrt(A1*A1+A2*A2);
if (B1>0) p=acos(B2);
else p=2*acos(-1)-acos(B2);
pop=sin(p)/(1-cos(p));
y=(pop*A3+B3)/(pop*sin(p)+1-cos(p));
x=(A3-sin(p)*y)/(1-cos(p));
printf("%.10f %.10f %.10f\n",x,y,p);
}
return 0;
}
1004:实在是郁闷,看错题目,导致最后做不出来,后来一交流才知道题目看错QAQ
题意:每个克隆人有N种能力,一个克隆人如果每种能力都大于等于另一个克隆人,则两者无法共存。现在给出每种能力的最大值,问最多几个人可以同时存在。
首先想到的是,如果二维的话,那么所有的点应该分布在对角线上,然后三维也是对角的面。。之后感觉没啥想法,就开始比较两个共存的条件。。这个时候回头一想,会不会是维度值的和有规律,结合前面的对角,就猜想各维度的值的和可能有规律。然后测了一下,发现都是sum/2,那么问题就被简化成A+B+C+D...=sum/2的不同个数有几个。
这个时候。。就跌入了神坑。。我每个维度的最大值看成了2000,这样sum最大为4*10^6,不管是背包还是记忆化搜索都是跪舔。。后来结束了才发现,2000的意思是sum最大为2000,真是哭瞎。。。
具体见代码吧,我是用记忆化搜索做的,应该还算比较简明
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define LL __int64
#define MOD 1000000007
int n,x[2010];
int dp[2010][2010];
int dfs(int wei,int X)
{
int a;
if (wei==n+1) return 0;
if (dp[wei][X]!=-1) return dp[wei][X];
if (X<0) return 0;
if (X==0) return 1;
int sum=0;
for (a=0;a<=x[wei+1];a++)
{
sum=(sum+dfs(wei+1,X-a))%MOD;
}
return dp[wei][X]=sum;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int sum=0;
scanf("%d",&n);
for (int a=1;a<=n;a++)
{
scanf("%d",&x[a]);
sum+=x[a];
}
int P=sum/2;
memset(dp,-1,sizeof(dp));
printf("%d\n",dfs(0,P));
}
return 0;
}
1005:
题意:给出一个连通图,起点随机定义,共走d步,问一个点没被走到的概率
好吧。。这题我实在是没啥好的想法,然后暴力上了........O(d*n^3).......竟然AC了,真是惊了个呆。。
后来发现其实可以优化到O(log (d)*n^3)........虽然效率还是很低,应该是代码写挫了........
思路就是枚举点,然后将这个点从这个图中删除,然后对剩下的点矩阵快速幂求概率。
挫代码奉上
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define LL __int64
double P[55],Q[55];
double whole[55];
bool lol[55][55];
int num[55];
struct Matrix
{
double mat[110][110];
int n;
Matrix(){}
Matrix(int _n)
{
n = _n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
mat[i][j]=0;
}
Matrix operator *(const Matrix &b)const
{
Matrix ret=Matrix(n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
{
double tmp=mat[i][k]*b.mat[k][j];
ret.mat[i][j]=(ret.mat[i][j]+tmp);
}
return ret;
}
};
Matrix quick(Matrix L,int x,int n)
{
Matrix ret=Matrix(n);
for (int a=0;a<n;a++)
ret.mat[a][a]=1;
while(x>0)
{
if (x&1) ret=ret*L;
L=L*L;
x/=2;
}
return ret;
}
int main()
{
int T,a,b,c,i;
int n,m,d,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&d);
memset(num,0,sizeof(num));
memset(lol,0,sizeof(lol));
for (a=1;a<=m;a++)
{
scanf("%d%d",&x,&y);
lol[x][y]=true;
lol[y][x]=true;
num[x]++;
num[y]++;
}
Matrix yuan(n);
for (a=0;a<n;a++)
for (b=0;b<n;b++)
{
if (lol[a+1][b+1]) yuan.mat[a][b]=1/double (num[a+1]);
}
Matrix hou(n);
for (int j=1;j<=n;j++)
{
hou=yuan;
for (a=1;a<=n;a++)
hou.mat[a-1][j-1]=0;
for (a=1;a<=n;a++)
{
if (a!=j) P[a]=1/double (n);
else P[a]=0.0;
}
whole[j]=0.0;
hou=quick(hou,d,n);
for (a=1;a<=n;a++)
{
Q[a]=0;
for (b=1;b<=n;b++)
{
Q[a]+=P[b]*hou.mat[b-1][a-1];
}
}
for (a=1;a<=n;a++)
{
if (a!=j) P[a]=Q[a];
else P[a]=0.0;
}
for (a=1;a<=n;a++)
whole[j]+=P[a];
}
for (a=1;a<=n;a++)
printf("%.10f\n",whole[a]);
}
return 0;
}
1007:水题。。这个不用说了吧。。排序然后题目怎么说就怎么做。
#include<map>
#include<cstdio>
#include<string.h>
#include<iostream>
#include <algorithm>
using namespace std;
#define maxn 11111
double mul=0.95;
double x[11111],a[11111];
int cmp(double a,double b){
return a>b;
}
int main(){
x[0]=1.0;
for(int i=1;i<=55;++i)x[i]=x[i-1]*0.95;
int n,_;scanf("%d",&_);
while(_--){
scanf("%d",&n);
for(int i=0;i<n;++i)scanf("%lf",&a[i]);
sort(a,a+n,cmp);
double ans=0;
for(int i=0;i<n;++i){
ans+=a[i]*x[i];
}
printf("%.10f\n",ans);
}
return 0;
}