ACM ICPC 2017 Warmup Contest 1(Nordic Collegiate Programming Contest 2016)

来源:互联网 发布:学而时之不亦说乎全文 编辑:程序博客网 时间:2024/05/24 07:09
国庆训练开始
由于部分原因,在家和队友做了训练,第一场,由于新疆icpc因19大推迟,使我们又多了大量时间,那么就开始吧。
其实这场感觉还不错,单人作战组队赛,4题,险些5题收场,还可以吧


首先看了前四题,发现并不是很可以做,于是,突然发现签到题在倒数第二题,赶快a了,跟一波步伐


J. Jumbled Compass

思路:纯粹的签到题,指针转法,顺时针逆时针比较一下大小就好了,注意一下度数取模,ac

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+10;int myabs(int k){    if(k>0)    {        return k;    }    else    {        return (-1) * k;    }}int main(){    int n1,n2;    while(scanf("%d%d",&n1,&n2)!=EOF)    {        int a = n2-n1;        if(a<0)        {            a += 360;        }        int b = myabs(360-a);        if(a<=b)        {            printf("%d\n",a);        }        else        {            printf("%d\n",(-1)*b);        }    }    return 0;}

G. Game Rank

思路:典型的细节模拟题,读清题,把题中每一个细节都考虑到就可以了
1.胜升败降
2.超分升级,负分降级
3.传奇不降
4.一星不降
5.六阶下三连胜加成
最后注意条件4零分时特判一下,并且传奇单独输出就好了

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e4+10;char game[maxn];int upgrade[26] = {0,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2};int main(){    while(scanf("%s",game)!=EOF)    {        int len = strlen(game);        int star = 0;        int myrank = 25;        int conwin = 0;        for(int i=0;i<len;i++)        {            if(game[i]=='W')            {                star++;                conwin++;                if(myrank>=6&&conwin>=3)                {                    star++;                }                if(myrank>0&&star>upgrade[myrank])                {                    star -= upgrade[myrank];                    myrank--;                }            }            else            {                conwin = 0;                if(myrank>0&&myrank<=20)                {                    star--;                    if(myrank==20&&star<0)                    {                        star++;                    }                }                if(star<0)                {                    myrank++;                    star += upgrade[myrank];                }            }        }        if(myrank==0)        {            printf("Legend\n");        }        else        {            printf("%d\n",myrank);        }    }    return 0;}



E. Exponial

思路:阶乘级幂指数运算,看了一眼直接飙飞的大数,毫无以为降幂公式咯
降幂公式,肯定不能是三角降幂,想到费马小定理降幂A^x%p=A^(x%(p-1))%p
这里要求p是素数,成立,然而,这里的模数显然过大了,还是不可做
于是想到欧拉降幂A^x%p=A^(x%ψ(p)+ψ(p))%p,这里ψ(p)为p的欧拉函数,这里欧拉函数就比较小了,完全是个可行的方案
这里的条件为x>ψ(p),那么分类讨论一下就好了,按样例中的5作为分界
然后最后一个问题,这里的n高达1e9,如果直接循环的话肯定会tle,然而其实可以发现一个小诀窍
exponial(n) %p= n^(exponial(n-1))%p;
再用欧拉降幂
exponial(n) %p=n^(exponial(n-1))%p=n^(exponial(n-1)%ψ(p)+ψ(p))%p
exponial(n) %p=F(exponial(n-1)%ψ(p))
F函数可以用快速幂算
于是,便可以递归了,偶然间发现,当模数即ψ(p)=1时,exponial(n-1)%ψ(p)=0,由于欧拉函数下降速度还是比较快的,于是这个大剪枝就完全可以将O(1e9)的复杂度降下了了,成功ac

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e6+10;int euler(int n){    int cnt = n;    for(int i=2; i * i <= n; i++)    {        if(n % i == 0)        {            cnt -= cnt / i;      //   m-m/p            while(n % i == 0)            {                n /= i;            }        }    }     if(n > 1)     {         cnt -= cnt / n;     }    return cnt;}long long Power(long long a0,long long k,long long mode){long long b0 = 1;while(k)//k>0{if(k&1)//k % 2 == 1{b0 = b0 * a0 % mode;}a0 = a0 * a0 % mode;k >>= 1; //k/=2;}return b0;}long long exponial(long long n,long long m){    if(m==1)    {        return 0;    }    if(n<=5)    {        long long now = 1;        for(int i=1;i<=n;i++)        {            now = Power(i,now,m);        }        return now;    }    else    {        //n %= m;        long long eulerc = euler(m);        long long mm = exponial(n-1,eulerc);        return Power(n,mm+eulerc,m);    }}int main(){    long long n,m;    while(scanf("%lld%lld",&n,&m)!=EOF)    {        printf("%lld\n",exponial(n,m));    }    return 0;}


 D. Daydreaming Stockbroker

思路:最后一题,又是个水题,本来以为会是个dp,后来发现并没有这么复杂,低价买,高价卖,模拟一遍就ok了

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+5;long long p[maxn];int main(){    int d;    while(scanf("%d",&d)!=EOF)    {        for(int i=1;i<=d;i++)        {            scanf("%lld",&p[i]);        }        long long sum = 100;        long long num = 0;        bool increase = false;        for(int i=2;i<=d;i++)        {            if(increase)            {                if(p[i]<p[i-1])                {                    sum += p[i-1] * num;                    num = 0;                    increase = false;                }            }            else            {                if(p[i]>p[i-1])                {                    long long tb = sum / p[i-1];                    if(tb > 1e5)                    {                        tb = 1e5;                    }                    sum -= p[i-1] * tb;                    num += tb;                    increase = true;                }            }        }        sum += num * p[d];        printf("%lld\n",sum);    }    return 0;}



 F. Fleecing the Raffle

思路:这题是后来补的,一开始队友做崩了,以为要高精度什么的,后来发现其实并不需要这么麻烦
就是一个排列组合公式C(1,k)*C(p-1,n)/C(p,n+k)
对于k,一开始想写个三分,后来找规律可以发现k=n / (p-1),向下取整
化简发现,分子分母刚好都有k项
分子为p*k*π(n-p+i),i=2~k
分母为(n+1)*π(n+i),i=2~k
于是写个循环,成功


#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+10;/*typedef long long LL;LL Power_mod(LL a, LL b, LL p){    LL res = 1;    while(b!=0)    {        if(b&1) res = (res*a)%p;        a = (a*a)%p;        b >>= 1;    }    return res;}LL Comb(LL a,LL b, LL p){    if(a < b) return 0;    if(a == b) return 1;    if(b > a-b) b = a-b;    LL ans = 1, ca = 1, cb = 1;    for(LL i=0; i<b; ++i)    {        ca = (ca*(a-i))%p;        cb = (cb*(b-i))%p;    }    ans = (ca*Power_mod(cb, p-2, p))%p;    return ans;}*/int main(){    int n,p;    while(scanf("%d%d",&n,&p)!=EOF)    {       int x = n / (p-1);       double res = double(x*p) / (n+1);       for(int i=2;i<=x;++i)       {           res *= double(n-p+i) / (n+i);       }       printf("%.9f\n",res);    }    return 0;}

文章地址:http://blog.csdn.net/owen_q/article/details/78177706

阅读全文
1 0