OneCode(天梯四) D:难度计算(题解)

一码学程题目链接(天梯四D):OneCode_tianti_4_D

此题是一道动归题,本人在写此题的时候根本没看出动归,居然在那SHAZIYIYANGDE枚举

结果证明,枚举是肯定不行的(想枚举到一分?这辈子都不可能)

我们可以分情况来看,当然,本题题目已经给出了所有情况:

No.1 所有数字都相同(1难度值)

No.2 数字以差值为1单调递增或递减(2难度值)

No.3 数字交替出现(4难度值)

No.4 数字成等差数列(5难度值)

No.5 数字不符合上列规律(10难度值)

细心读题,我们还可以在题目中发现 “按3至5位数字分割” 的条件

这再次向我们说明了认真审题的重要性 

 (我就没看到这个条件)

已经知道所有情况的可能性,我们就可以做出多个函数来处理这些情况,代码实现如下:

int find_same(int b,int e)  //第一种情况
{
    int t=mapn[b];
    for(int i=b;i<=e;i++)
    {
        if(mapn[i]!=t) return 0;     
    }
    return 1;
}
int find_wall(int b,int e) 
//第三种情况
{
    int t=mapn[b];
    int h=mapn[b+1];
    int j=0;
    for(int i=b;i<=e;i++)
    {
        j++;
        if(j%2==1)
        {
            if(mapn[i]!=t) return 0;     
        }
        else 
        {
            if(mapn[i]!=h) return 0;
        }
        
    }
    return 1;
}
int find_stair(int b,int e) 
//第二和第四种情况
{
    int t=mapn[b]-mapn[b+1];
    int s;
    if(t==0) return 0;
    if(t==1||t==-1) s=1;
    else s=2;
    for(int i=b;i<e;i++)
    {
        if(mapn[i]-mapn[i+1]!=t) return 0;
    }
    return s;
}
int BamderBox(int a,int b)
{
    if(find_same(a,b)) return 1;
    else 
    if(find_wall(a,b)) return 4;
    else 
    if(find_stair(a,b)==1) return 2;
    else 
    if(find_stair(a,b)==2) return 5;
    else return 10; 
//第五种情况(只有 "return 10" 哦)
}

以上,真正是处理情况的函数其实只有 find_same 、find_wall 和 find_stair

而 BamderBox 是对它们返回的值进行判断,再传给主程序

看到这里,可能有人会问:“五种情况。这里加上 BamderBox 也才只有四个函数,不够啊!”

那你肯定就是没有认真读我给出的代码了,旁边都打了注释了的

(因为第二和四种情况太像了,所以本人将它们使用同一个函数解决,再加上简单if就行了)

【重点】本人设立这几个函数的目的,就是想用它们来查看a至b中的数为(拼音第二声)第几个规律,并在函数BamderBox中返回其难度值

所以我们可以写出动归主程序:

int main()
{
    cin>>ch;
    l=strlen(ch);
    
    for(int i=1;i<=l;i++)
    {
        mapn[i]=ch[i-1]-'0';
    }
    memset(f,9999999,sizeof(f));f[0]=0;
    for(int i=3;i<=l;i++)
    {
        
for(int j=3;j<=5;j++)
        {
            if(i<j) break;
            f[i]=min(f[i],f[i-j]+BamderBox(i-j+1,i));
        }
    }
    cout<<f[l]<<endl;
    return 0;
}

(看这里的时候要回想下“按3至5位数字分割” 的条件,不然红色代码段会很难看懂的哦~)

所以我们就可以写出一个完整的D题AC代码啦

#include<iostream>                                                                                                                                                                          #include<cstdio>                                                                                                                                                                          #include<cmath>
#include<cstring>

using namespace std;
int mapn[10000001];
int f[1000001];
char ch[10000001];
int l,ans=0;
int find_same(int b,int e)
{
    int t=mapn[b];
    for(int i=b;i<=e;i++)
    {
        if(mapn[i]!=t) return 0;     
    }
    return 1;
}
int find_wall(int b,int e)
{
    int t=mapn[b];
    int h=mapn[b+1];
    int j=0;
    for(int i=b;i<=e;i++)
    {
        j++;
        if(j%2==1)
        {
            if(mapn[i]!=t) return 0;     
        }
        else 
        {
            if(mapn[i]!=h) return 0;
        }
        
    }
    return 1;
}
int find_stair(int b,int e)
{
    int t=mapn[b]-mapn[b+1];
    int s;
    if(t==0) return 0;
    if(t==1||t==-1) s=1;
    else s=2;
    for(int i=b;i<e;i++)
    {
        if(mapn[i]-mapn[i+1]!=t) return 0;
    }
    return s;
}
int BamderBox(int a,int b)
{
    if(find_same(a,b)) return 1;
    else 
    if(find_wall(a,b)) return 4;
    else 
    if(find_stair(a,b)==1) return 2;
    else 
    if(find_stair(a,b)==2) return 5;
    else return 10;
}
int main()
{
    cin>>ch;
    l=strlen(ch);
    
    for(int i=1;i<=l;i++)
    {
        mapn[i]=ch[i-1]-'0';
    }
    memset(f,9999999,sizeof(f));f[0]=0;
    for(int i=3;i<=l;i++)
    {
        for(int j=3;j<=5;j++)
        {
            if(i<j) break;
            f[i]=min(f[i],f[i-j]+BamderBox(i-j+1,i));
        }
    }
    cout<<f[l]<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值