练习赛20150510

练习赛地址http://acm.hrbust.edu.cn/vj/index.php?c=contest-contest&cid=70

a.水。。。

b.暴力打表。。。

c.给四个正方形,求一个能覆盖他们的正方形的面积,其实能覆盖两个最大的正方形就一定能覆盖四个正方形,所以输出两个最大正方形的边长和~\(≧▽≦)/~啦啦啦

d.组合数学,dp[i][j],前表示i个里选j个有多少种情况。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const long long maxa = 104;
const long long mod = 1000000007;
long long dp[maxa][maxa*maxa];
long long a[maxa*maxa];
long long s[maxa*maxa];

long long c[maxa*maxa][maxa];
int main(){
    for(long long i=0;i< maxa*maxa;i++)
    {
        for(long long j=0;j<maxa;j++)
        {
            if(!j||i==j)
                c[i][j]=1;
            else
                c[i][j]=c[i-1][j-1]+c[i-1][j];
                c[i][j] %= mod;

        }
    }
    long long n;
    long long cas = 1;
    while(cin>>n){
        memset(dp, 0, sizeof(dp));
        for(long long i =0; i < n; i++){
            cin>>a[i];
            if(i == 0) s[i] = a[i];
            else s[i] = s[i-1]+a[i];
        }
        for(long long i = 0;i < n; i++){
            if(i == 0){
                for(long long j = 0; j <= a[i]; j++){
                    dp[i][j] = 1;
                }
            }else{
                for(long long j = 0; j <= a[i]; j++){
                    for(long long k = 0;k <= s[i-1]; k++){
                        dp[i][j+k] += dp[i-1][k]*(c[j+k][j]);
                        dp[i][j+k] %= mod;
                    }
                }
            }
        }
        long long ans = 0;
        for(long long i = 1; i <= s[n-1]; i++){
            ans += dp[n-1][i];
            ans %= mod;
        }
        cout<<"Case "<<cas++<<": "<<ans<<"\n";
    }
}
View Code

e.简单数位dp

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const long long maxa = 11;
long long dp[maxa][maxa*2];
char str1[maxa], str2[maxa], str3[maxa];
char str[1111];
int main(){
    int cas = 1;
    //while(scanf("%[^+]%*c%[^=]%*c%[^\n]\n", str1, str2, str3)!=EOF){
    //scanf("%*[ \n]");
    while (gets(str)) {
        //scanf("%*[ \n]");
        sscanf(str, "%[^+]+%[^=]=%s", str1, str2, str3);
        long long l1 = strlen(str1);
        long long l2 = strlen(str2);
        long long l3 = strlen(str3);
        memset(dp, 0, sizeof(dp));
        //printf("%s\n%s\n%s\n", str1, str2, str3);
        //printf("%d %d %d\n", l1, l2, l3);
        if(l1 > l3 || l2 > l3){
            printf("Case %d: %d\n", cas++, 0);//printf("//");
            continue;
        }
        for(long long i = 1;i <= l3; i++){
            if(i == 1){
                //printf("++%c\n",str1[l1-1]);
                for(long long i1 = 0; i1 < 10; i1++){

                    if(str1[l1-1] != '?' && i1 != str1[l1-1]-'0')continue;//printf("**%d\n", i1);
                    for(long long i2 = 0; i2 < 10; i2 ++){
                        if(str2[l2-1] != '?' && i2 != str2[l2-1]-'0')continue;
                        //printf("*%d %d\n", i1, i2);
                        long long sum = i1 +i2;
                        if(str3[l3-1] != '?' && sum % 10 != str3[l3-1]-'0')continue;
                            dp[i][sum] ++;
                    }
                }
                continue;
            }
            for(long long k = 0; k < 20; k++){
                if(i != 1 && dp[i-1][k] == 0)continue;
                //printf("%c %c %c\n", str1[l1-i], str2[l2-i], str2[l3-i]);
                for(long long i1 = 0; i1 < 10; i1++){
                    if(i1 == 0 && i == l1)continue;
                    if(i > l1 && i1) continue;
                    if(i <= l1 && str1[l1-i] != '?' && i1 != str1[l1-i] - '0')continue;
                    for(long long i2 = 0; i2 < 10; i2++){
                        if(i > l2 && i2)continue;
                        if(i == l2 && i2 == 0) continue;
                        if(i <= l2 && str2[l2-i] != '?' && i2 != str2[l2-i]-'0')continue;
                        long long sum = i1+i2 + k/10;
                        if(str3[l3-i] != '?' && str3[l3-i]-'0' !=sum % 10)continue;
                        //printf("--%d %d %d %d\n", i1, i2, sum , k);
                        dp[i][sum] += dp[i-1][k];
                    }
                }
            }
        }
        long long ans = 0;
        for(long long i = l3==1 ? 0:1; i < 10 ; i++){
            //printf("%d ", dp[1][i]);
            ans += dp[l3][i];
        }
        printf("Case %d: ", cas++);
        cout << ans << endl;
    }
}
/*
100+?=???
*/
View Code

f.划分树模板题,但是没带。。。。

g.水题,栈操作

 

posted @ 2015-05-12 11:54  icodefive  阅读(201)  评论(0编辑  收藏  举报