BZOJ 1026 Scoi2009 windy数
1026: [SCOI2009]windy数
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8765 Solved: 3957
[Submit][Status][Discuss]
Description
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?
Input
包含两个整数,A B。
Output
一个整数
Sample Input
【输入样例一】
1 10
【输入样例二】
25 50
1 10
【输入样例二】
25 50
Sample Output
【输出样例一】
9
【输出样例二】
20
9
【输出样例二】
20
HINT
【数据规模和约定】
100%的数据,满足 1 <= A <= B <= 2000000000 。
Source
我觉得网上大部分的题解写的有点扯
只用到了一小部分dp,其他的都是模拟
首先dp预处理出来f[i][j]表示以最高位为j的i位数总共含有多少个windy数
我们求n~m的windy数,也就是求1~m的windy数-1~n的windy数
感觉没有实际的例子不是很好说代码是怎么运行的,举个例子吧
比如说2596476
首先1~1999999之间的所有windy数都是符合条件的
2000000~2499999之间的windy数也都是符合条件的
2500000~2589999之间的windy也都是符合条件的
同理
2590000~2595999 2596000~2596399
2596400~2596479 2596470~2596479
这些区间中的windy数都是符合条件的
我们依次去枚举这些区间,把答案累加到sum上
具体数先看代码,最后把1~n中的windy数和1~m中的windy数相减即为答案
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int f[20][15]={};
string str1,str2;
void init(){
cin>>str1;cin>>str2;
}
void solve(){
for(int i=0;i<=9;i++){
f[1][i]=1;
}
for(int i=2;i<=15;i++){
for(int j=0;j<=9;j++){
for(int k=0;k<=9;k++){
if(abs(j-k)>=2) f[i][j]+=f[i-1][k];
}
}
}
int str1l=str1.size();int str2l=str2.size();
int sum1=0;int sum2=0;
for(int i=1;i<str1l;i++){
for(int j=1;j<=9;j++){
sum1+=f[i][j];
}
}
for(int i=1;i<str2l;i++){
for(int j=1;j<=9;j++){
sum2+=f[i][j];
}
}
for(int i=1;i<str1[0]-'0';i++){
sum1+=f[str1l][i];
}
for(int i=1;i<str2[0]-'0';i++){
sum2+=f[str2l][i];
}
for(int i=0;i<str1l-1;i++){
int tn=str1[i]-'0';
int tnt=str1[i+1]-'0';
for(int j=0;j<tnt;j++){
if(abs(tn-j)>=2) sum1+=f[str1l-i-1][j];
}
if(abs(str1[i+1]-str1[i])<2) break;
}
for(int i=0;i<str2l;i++){
int tn=str2[i]-'0';
int tnt=str2[i+1]-'0';
for(int j=0;j<tnt;j++){
if(abs(tn-j)>=2) sum2+=f[str2l-i-1][j];
}
if(abs(str2[i+1]-str2[i])<2) break;
if(i==str2l-2) sum2++;
}
cout<<sum2-sum1<<endl;
}
int main(){
//freopen("All.in","r",stdin);
//freopen("zhang.out","w",stdout);
init();
solve();
return 0;
}
对拍代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main(){
freopen("All.in","w",stdout);
srand(int(time(NULL)));
int n=rand()%100007+1;int m=rand()%100007+1;
if(n>m) swap(n,m);
cout<<n<<' '<<m<<endl;
return 0;
}

浙公网安备 33010602011771号