130807hud第五场多校结题报告

来源:互联网 发布:淘宝专卖店是正品吗 编辑:程序博客网 时间:2024/05/22 14:52

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 1000000007long 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;}