130807hud第五场多校结题报告

1004 Laser Beam

传送门

一道很纠结的题,最初打算从角度入手,可是始终无法找到好的方法。后来发现可以把给出的大三棱镜划分为多个小三角形,每个小三角形中与入射点对称的点则是入射光线可能到达的点。

之后,我们将三角形进一步缩小后就能找出每一次入射不同角度的变化,进一步能发现如果反射n次则反射点必在第(n+3)/2行(指小三角形的行数)

之后只要找出并去重和去除不成立的点就能出结果了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int n,s,shu,ans;
int pr[1005];

void change(int wei,int shug,int ch)
{
    if(wei == shu)
    {
        int get = (shug % 3) * (n % 3) % 3 * shug;
        if(s >= get)
            ans += ((s - get) / 3 / shug + 1) * ch;
    }
    else
    {
        change(wei+1,shug,ch);
        change(wei+1,shug*pr[wei],-ch);
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        if(n % 2 == 0 || n % 3 == 0)
        {
            printf("0\n");
            continue;
        }
        s = (n + 3) / 2;
        shu = 0;
        for(int i=2;i*i<=s;i++)
        {
            if(s % i == 0)
            {
                pr[shu] = i;
                while(s % i == 0)
                {
                    s = s / i;
                }
                shu++;
            }
        }
        if(s != 1)
        {
            pr[shu] = s;
            shu++;
        }
        ans = 0;
        s = (n + 3) / 2;
        change(0,1,1);
        printf("%d\n",ans);
    }
    return 0;
}

1005 Another Graph Game

传送门

一道很伤心的刷版题,在此膜拜宝哥的YY能力^_^

题目说的好像很复杂,又有点又有边的,但是,如果我们把边拆开分给对应的两个点的话,那么就变成了单纯的数组排序问题。

可惜我这样的题竟然还因为数据范围的问题W了两次,伤心啊T_T


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int n,m;
double s[100005];
int u,v;
double w,ans;

bool cmp(double x,double y)
{
    return x > y;
}

int main()
{
    while(scanf("%d%d",&n,&m) != EOF)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%lf",&s[i]);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%lf",&u,&v,&w);
            s[u-1] += w / 2.0;
            s[v-1] += w / 2.0;
        }
        sort(s,s+n,cmp);
        ans = 0;
        for(int i=0;i<n;i += 2)
        {
            ans += s[i] - s[i + 1];
        }
        printf("%.0lf\n",ans);
    }
    return 0;
}

1006Magic Pen 6

传送门

又是一道刷版题。

目测是因为数据比较水的关系,N^2的算法也一样过,用存取模数的方法来做也仅仅只是压缩了点时间而已,不多说了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int n,m,sum,ans;
int s[100005];
int mo[10005];

int main()
{
    while(scanf("%d%d",&n,&m) != EOF)
    {
        sum = 0;
        ans = 0;
        memset(mo,-1,sizeof(mo));
        mo[0] = 0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&s[i]);
            sum += s[i];
            sum = (sum % m + m) % m;
            if(mo[sum] == -1)
            {
                mo[sum] = i + 1;
            }
            else
            {
                if(i + 1 - mo[sum] > ans)
                {
                    ans = i + 1 - mo[sum];
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

1009Partition

传送门

一道老题,规律之类的网上有好多,只要按五角数来进行预处理就能很简单的输入输出了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;
#define mod 1000000007
long long int f[100001];
long long int f1[100001];
long long p[100001];
void ff()
{
    int i;
    for(i=0;i<=5000;i++)
    {
        f[i]=i*(3*i-1)/2;
        f1[i]=f[i]+i;
    }
}

void pp()
{
    memset(p,0,sizeof(p));
    p[0]=1;
    p[1]=1;
    p[2]=2;
    p[3]=3;
    p[4]=5;
    int i,j;

    for(i=5;i<=100001;i++)
    {
        int ans=1;
        for(j=1;;j++)
        {
            if((i-f[j])<0&&(i-f1[j])<0)
                break;
            if((i-f[j])>=0)
                p[i]=(p[i]+(ans*p[i-f[j]])+mod)%mod;
            if((i-f1[j])>=0)
                p[i]=(p[i]+(ans*p[i-f1[j]])+mod)%mod;
            ans*=(-1);
        }
    }
}
int main()
{
    ff();
    int T;
    int i,j;
    int n;
    pp();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        printf("%I64d\n",(p[n]+mod)%mod);
    }
    return 0;
}

1011k-th point

传送门

多面球体问题,代码很简单,但是中间的推规律的过程很伤心。

有兴趣的可以自己上网找推的过程,是一个很有趣的过程。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

int main()
{

    int t;
    scanf("%d",&t);
    while(t--)
    {
        double p,n,k;
        scanf("%lf%lf%lf",&p,&n,&k);
        double s=1.0;
        for(int i=n-k; i<=n; i++)
        {
            s*=(i*p/(i*p+1));
        }
        printf("%.9lf\n",s);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值