uva Alberta Collegiate Programming Contest 2011 总结

来源:互联网 发布:excel数据分类排序 编辑:程序博客网 时间:2024/06/08 08:50

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=13&page=show_contest&contest=297


最近来看我博客的实在是太少了,当然评论也就更少了,上一个评论还是去年的事,还是我同学评的,囧

周六的时候,也就是4月7号,周六晚上我弄的并不是很认真,我队友他们也没有兴趣,最后的结果就是,我们3个题,当然这个结果我还是比较认同的。

最近喜欢上做套题了,莫名其妙,哎,今天老师还夸了我几句,高兴,但是我知道,我的水平还是有限的,我还得继续努力!加油,come on!嘻嘻

额,我敲了好久,莫名奇妙的弄没了,fuck,懂了,我不应该敲那么多的东东的 简短点

Problem A - Bits and Pieces 思路:判断每一位的情况,然后是第一个不确定的为a为1 b为0 其他位恰好相反,ok最简单的一题

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int a[40];int main(){    int t;    cin >> t;    int c,d;    while( t-- )    {        cin >> c >> d;        bool re = 1;;int len = 0;        while(c || d)        {            if((d&1) == 1 && (c&1) == 1) a[len] = 1;            else if((d&1) == 1 && (c&1) == 0) a[len] = 2;            else if((d&1) == 0 && (c&1) == 1) {re = 0;break;}            else if((d&1) == 0 && (c&1) == 0) a[len] = 0;            len++;            c = c>>1;            d = d>>1;        }        if(re == 0) cout << "-1\n";        else        {            bool first = 0;            int aa = 0,bb = 0;            for(int i = len-1;i >= 0;i--)                if(a[i] == 1)                {                    aa = aa*2+1; bb = bb*2+1;                }else if(a[i] == 0)                {                    aa *= 2; bb *= 2;                }else                {                    if(first == 0)                    {                        aa = aa*2+1;bb = bb*2;                        first = 1;                    }else                    {                        aa = aa*2;bb = bb*2+1;                    }                }            cout << bb << " " << aa << "\n";        }    }    return 0;}
Problem C - How Many... in 3D! 这个题如果你弄过二维的那个填充的问题的话,你就会想到递推公式,然后解决

这个问题的递推公式是:dp[i] = 2*dp[i-1] + 5*dp[i-2] + 4*dp[i-3] + 4*dp[i-4] + 4*dp[i-5] + ... + 4*dp[0];

ok,这个这个就这么解决了,当然做的时候,三维的东西弄了好久

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;const long long P = 1000000007;long long dp[1000010];long long re[1000010];long long re42[1000010];int main(){    dp[0] = 1;    dp[1] = 2;    dp[2] = 9;    dp[3] = 32;    re[0] = 1;    re[1] = 3;    re[2] = 12;    re[3] = 44;    for(int i = 4;i < 1000004;i++)    {        dp[i] = (dp[i-1]*2 + dp[i-2]*5 + re[i-3]*4)%P;        re[i] = (re[i-1] + dp[i])%P;    }    int t;    cin >> t;    while( t-- )    {        int n;        scanf("%d",&n);        cout << dp[n] << "\n";        //printf("%I64d\n",dp[n]);    }    return 0;}
 

ok,进入第三题:

Problem D - Pieces and Bits 这个题其实和格雷码有关 当然格雷码大家应该会求吧,不会百度,呵呵,然后就是这个题和格雷码的不同,这个题要求的相邻两个编码应该是有且只有一个相同,ok,我就把偶数位的每一位进行了变化,0->1 1->0;遗憾的是,这个变换之后为什么仍然是1-n的序列,我还是没弄明白,要是有人能弄明白,教教我


#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>using namespace std;int code[30];int code2[30];void gray2(int len,int n){    memset(code,0,sizeof(code));    for(int i = 0;i < len;i++)        if(( n & (1<<i)) != 0)            code[i] = 1;    code2[len-1] = code[len-1];    for(int i = len-2;i >= 0;i--)        code2[i] = code[i] ^ code[i+1];}int main(){    int n,t;    cin >> t;    while(t--)    {        cin >> n;        for(int i = 0;i < (1<<n);i++)        {            gray2(n,i);            int re = 0;            if(i % 2 == 0) for(int j = n-1;j >= 0;j--)  code2[j] = 1-code2[j];            //for(int j = n-1;j >= 0;j--) cout << code2[j];            for(int j = n-1;j >= 0;j--) re = re * 2 + code2[j];            printf("%d\n",re);        }    }    return 0;}

下一个我做出来的题是:Problem E - Casino Advantage 这个题是概率,其实就是递推的概率,不是很难吧,这套题难道我的是读题,赛后看了看这个题,不是很难!!
#include <iostream>#include <stdio.h>#include <string.h>using namespace std;struct note{    long long a,b;}dp[200][200];long long gcd(long long a,long long b){    while(b)    {        long long t=a%b;        a=b;b=t;    }    return a;}note add(note a,note b){    note re;    re.b = a.b*b.b;    re.a = a.a*b.b + b.a*a.b;    long long d = gcd(re.a,re.b);    re.a = re.a / d;    re.b = re.b / d;    return re;}note mul(note a,note b){    note re;    re.a = a.a * b.a;    re.b = a.b * b.b;    long long d = gcd(re.a,re.b);    re.a = re.a/d;    re.b = re.b/d;    return re;}int main(){    //cout << gcd(1,0) << " " << gcd(0,1);    int t;    cin >> t;    while(t--)    {        int n,m,k;        n = 140;        for(int i = 0;i < n;i++)        {            for(int j = 0;j < n;j++)            {                dp[i][j].a = 0;                dp[i][j].b = 1;            }        }        dp[0][0].a = 1;        dp[0][0].b = 1;        cin >> n >> m >> k;        for(int i = 1;i <= m;i++)        {            for(int j = 0;j <= k;j++)            {                note no ;                no.a = j;no.b = n;                note yes;                yes.a = n-j+1;yes.b = n;                if(j != 0)                    dp[i][j] = add( mul(dp[i-1][j] , no) , mul(dp[i-1][j-1],yes) );                else dp[i][j] = mul( dp[i-1][j],no );            }        }        if(dp[m][k].a == 0) cout << "0\n";        else if(dp[m][k].b == 1) cout << dp[m][k].a << "\n";        else  cout << dp[m][k].a << "/" << dp[m][k].b << "\n";    }    return 0;}
上面的注意分数加减,还得注意long long ,你懂的
Problem H - Let's call SPaDe a SPaDe 这个是我最后做的题,也是一个没有做出来的题

思路不是很难,我用的是dp加kmp做的,遗憾的是都是wa,wa了好几次,悲哀,如果有人乐意的话,我贴代码,你们瞅瞅,这个代码是wa的!!

我是百思不得其解啊!!

2012年4.12添加,这个题终于a掉了,原因是那个kmp我并没有认真的学习,我队友给我的模板我就套用上了,结果出了一点小差错!!以至于wa了那么久!!

ok,贴一下可以ac的代码!

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int dp[200];char str[200];int next[200];char dis[200];void get_next(int n){    memset(next,0,sizeof(next));    int i,j=-1;    next[0]=-1;    for(i=1;i<=n;i++){     //dis[j]是不是可以理解为i的前一个字符的next值所指想的字符        while(j>-1&&dis[j+1]!=dis[i])j=next[j];        if(dis[j+1]==dis[i])j++;        next[i]=j;    }}int get(int start,int end)//前闭后开{    int n = end-start;    for(int i = 0;i < n;i++) dis[i] = str[start+i];    dis[n] = '\0';    get_next(n);    int l=(n-1)-next[n-1];    //cout << n << " " << l << "\n";    if(n% l == 0)        return n/l;    else return 1;// 我个大笨蛋居然忘了写这个情况!}int getNum(int t){    int re = 0;    while(t)    {        re++;        t = t / 10;    }    return re;}int main(){    //getNum(11);    int t;    //cin >> t;    scanf("%d",&t);    //getchar();    while(t--)    {        scanf("%s",str);        //gets(str);        int len = strlen(str);        dp[0] = 0;        dp[1] = 1;        for(int i = 2;i <= len;i++)        {            dp[i] = 1212000;            for(int j = 0;j < i;j++)            {                int t = get(j,i);//t得到的是重复次数                int len = i-j;                int ll = len/t;                if(  len < ll + 2 + getNum(t)  )                    dp[i] = min( dp[i],dp[j] + len );                else                    dp[i] = min( dp[i],dp[j] + ll + 2 + getNum(t) );            }        }        printf("%d\n",dp[len]);    }    return 0;}



uva上的 这套题,怎么说呢??诡异的地方很多,应该叫trick吧,最后的这个还是没想明白有什么trick

加油!!


原创粉丝点击