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; }