2014 ACM/ICPC Asia Regional Anshan Online HDU 4998 HDU 5000 HDU 5001 HDU 5003

表示这场网络赛好伤,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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值