2015 Multi-University Training Contest 7

注:只看了1005&&1007,个人水平比较low,

1005 - The shortest problem

乍看一眼,有点像前几天水的一道数论水题,说求一个数(2*10^9)的每位数之和,然后与此题无关系,其实题目就是不断求各位数的和然后补充上去,执行t次后判断得到的数时候能被11整除,很明显是有规律的,此数已经十几万位的数,不能直接%11,所以就会发现其实被11整除的数(只需判断奇数位的和与偶数位的和之差 %11==0  即可),然后然后就模拟,暴力求奇数位和偶数位的和~

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 10000010
using namespace std;
char num[N];
int a[15];
int main(){
    int n,t,T=1;
    while(scanf("%d%d",&n,&t)!=EOF){
        if(n==-1&&t==-1) break;
        int k=1,t1=0,t2=0;
        int tmp=0;
        for(int i=0;i<=t;i++){
            int f=0;
            while(n){
                tmp+=n%10;
                a[f++]=n%10;
                n/=10;
            }
            for(int j=f-1;j>=0;j--){
                if(k&1) t1+=a[j];
                else t2+=a[j];
                k++;
            }
            //cout<<tmp<<endl;
           // cout<<t1<<" "<<t2<<endl;
            n=tmp;
        }
        if((t1-t2)%11==0) printf("Case #%d: Yes\n",T++);
        else printf("Case #%d: No\n",T++);
    }
    return 0;
}


1007-Gray code

啊~!DP[N][2],可惜一开始没想到还得需要一个vis[N][2]用来标记该位置是否可能存在1或0。。题目中加所谓point的条件就是某位与前一位不同时为1或0。。DP方程的话直接看代码吧。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 200010
int dp[N][2],num[N];
bool vis[N][2];
char str[N];
int main(){
    int T;
    scanf("%d",&T);
    for(int k=1;k<=T;k++){
        scanf("%s",str+1);
        int n=strlen(str+1);
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        memset(dp,0,sizeof(dp));
        memset(vis,false,sizeof(vis));
        vis[0][0]=true;
        for(int i=1;i<=n;i++){
            if(str[i]=='0') vis[i][0]=true;
            else if(str[i]=='1') vis[i][1]=true;
            else vis[i][0]=vis[i][1]=true;
        }
        for(int i=1;i<=n;i++){
            if(str[i]=='?'){
                if(vis[i-1][1]) dp[i][0]=max(dp[i-1][1]+num[i],dp[i][0]);
                if(vis[i-1][0]) dp[i][0]=max(dp[i-1][0],dp[i][0]);
                if(vis[i-1][0]) dp[i][1]=max(dp[i-1][0]+num[i],dp[i][1]);
                if(vis[i-1][1]) dp[i][1]=max(dp[i-1][1],dp[i][1]);
            }else if(str[i]=='0'){
                if(vis[i-1][1]) dp[i][0]=max(dp[i-1][1]+num[i],dp[i][0]);
                if(vis[i-1][0]) dp[i][0]=max(dp[i-1][0],dp[i][0]);
            }else{
                if(vis[i-1][0]) dp[i][1]=max(dp[i-1][0]+num[i],dp[i][1]);
                if(vis[i-1][1]) dp[i][1]=max(dp[i-1][1],dp[i][1]);
            }
        }
        printf("Case #%d: %d\n",k,max(dp[n][0],dp[n][1]));
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/const_qiu/article/details/47423635