一码学程题目链接(天梯四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;
}