套题分析2013杭电多校测试一

4602.Partition

http://acm.hdu.edu.cn/showproblem.php?pid=4602

快速幂+公式

解:主要是推到公式,然后快速幂。(水)

任务:推导公式+快速幂实现。

附:ac代码

#include<stdio.h>
#define MOD 1000000007
#include<iostream>
using namespace std;
__int64 QuickPow(__int64 a,__int64 b)
{
    __int64 ans = 1;
    while(b>0)
    {
        if(b&1)    ans = (ans*a) %MOD;
        b>>=1;
        a=    (a*a) % MOD;
    }
    return ans;
}
int main()
{
    __int64 t,n,k,ans;
    scanf("%I64d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&n,&k);
        if(k>n) { printf("0\n");continue; }
        if(n==k)        printf("1\n");
        else if( 1 == (n-k) )    printf("2\n"); 
        else 
        {
            ans = (n-k+3)%MOD;    k=n-k-2;      ans=ans*QuickPow(2,k);
            printf("%I64d\n",ans%MOD);
        }
    }
    return 0;
}


4604.Deque

Lis  nlogn 模板 (可以参考:http://blog.csdn.net/u010489389/article/details/9456411)

Lis算法中的二分nlogn实现,dp实现会超时,nlogn算法掌握的有点不太牢固,重点看看该算法。

任务:Lis nlogn模板 + dp[ i ] 作用(重点理解),upper_bound()和 lower_bound()函数的用法,返回值。

附:ac代码:

这个题目测试数据有点问题,测试数据太弱,几乎一般的代码都能ac掉。(耗费了我三天,终于ac掉了)。
#include<stdio.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
#include<iostream>
#include<algorithm>
using namespace std;
int w[100005],dp1[100005],dp2[100005],same1[100005],same2[100005],n;
void up()
{
    int stack[100005],a,b,len;
    memset(stack,1,sizeof(stack));
    stack[0] = w[0];    len = dp1[0] = same1[0] = 1;
    for(int i=1;i<n;i++)
    {
        a = lower_bound(stack,stack+n,w[i])-stack;
        b = upper_bound(stack,stack+n,w[i])-stack;
        same1[i] = b - a + 1;
        if(w[i]>=stack[len-1]) { stack[len++] = w[i]; dp1[i] = len; }       //注意等号
        else{
            int pos = upper_bound(stack,stack+n,w[i]) - stack;              //注意查找区间
            stack[pos] = w[i];
//            cout<<"pos = "<<pos<<endl;
            dp1[i] = pos + 1;
        }
    }
//    for(i=0;i<n;i++)cout<<dp1[i]<<endl;
    return ;
}
void down()
{
    int stack[100005],a,b,len;
    memset(stack,1,sizeof(stack));
    stack[0] = w[0];    len = dp2[0] = same2[0] = 1;
    for(int i=1;i<n;i++)
    {
        a = lower_bound(stack,stack+n,w[i])-stack;
        b = upper_bound(stack,stack+n,w[i])-stack;
        same2[i] = b - a + 1;
        if(w[i]>=stack[len-1]) { stack[len++] = w[i]; dp2[i] = len; }
        else{
            int pos = upper_bound(stack,stack+n,w[i]) - stack;
            stack[pos] = w[i];
            dp2[i] = pos + 1;
        }
    }
//    for(i=0;i<n;i++)cout<<dp2[i]<<endl;
    return ;
}
int main()
{
    int t,i,j;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(i=0;i<n;i++)cin>>w[i];
        reverse(w,w+n);
    //    for(i=0;i<n;i++)cout<<w[i]<<" ";cout<<endl;
        up();
        for(i=0;i<n;i++)
            w[i] = -w[i];
        down();
    //    for(i=0;i<n;i++)cout<<"dp1[i] = "<<dp1[i]<<"  dp2[i] = "<<dp2[i]<<"  same1[i] ="<<same1[i]<<"  same2[i] = "<<same2[i]<<endl;
        int res;    res=0;
        
        for(i=0;i<n;i++)
        {
            res = max(res, dp1[i] + dp2[i] - min(same1[i],same2[i]) );
        }
        cout<<res<<endl;
        
    }
    return 0;
}



4608.I-number

大数模板

大数处理问题,注意:该题目要前导0,此处有点特殊。

任务:大数模板。教材:麦森数处理、求和模板、刘书入门经典:大数模板(可以缓)

附:ac代码

include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
char a[100005];
int b[100005];
int main()
{
    int t,i,len,j=0,sum;
    cin>>t;
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%s",a);
        len = strlen(a);                                
        j=0;    for(i=len-1;i>=0;i--)b[i] = a[j++]-'0';        
        for(i=1;i<=20;i++)
        {
            b[0]+=1;
            for(j=0;j<len;j++)if(b[j]>9)
            {
                b[j]-=10;
                b[j+1]++;
            }else break;                                    //for(i=len-1;i>=0;i--)cout<<b[i];cout<<"     ";
            if(j==len)len++;
            sum=0;
            for(j=0;j<=len;j++)
            {
                sum+=b[j];
            }                                                //cout<<"sum = "<<sum<<endl;
            if(0 == sum%10)break;
        }
    //    for(i=len;i>=0;i--)if(b[i])break;
        for(j=len-1;j>=0;j--)printf("%c",b[j]+'0');;cout<<endl;

    }
    return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值