NC17867. 明七暗七
描述
输入描述
输入两个整数m和n。(1 ≤ m, n ≤ 1012)
输出描述
输出一个整数,表示m以后第n个需要拍手的数字。
示例1
输入:
30 7
输出:
57
示例2
输入:
56 1
输出:
57
C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 504K, 提交时间: 2018-10-28 10:43:48
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL dp[20][10]; LL m,n; int num[20]; LL g (int p,int mod,bool limit) { if (!p) return !(mod==0); if (!limit&&dp[p][mod]) return dp[p][mod]; int k=9; if (limit) k=num[p]; LL sum=0; for (int i=0;i<=k;i++) if (i!=7) { int t=(mod*10+i)%7; sum+=g(p-1,t,limit&&(i==k)); } if (!limit) dp[p][mod]=sum; return sum; } LL f (LL x) { int cnt=0; LL t=x; while (x) { num[++cnt]=x%10; x=x/10; } return t-g(cnt,0,1); } int main () { scanf ("%lld %lld",&m,&n); LL l=m,h=m+7*n,k=f(m)+n; while (l<h) { LL mid=(l+h)/2; LL tmp=f(mid); if (tmp>=k) h=mid; else l=mid+1; } printf("%lld\n", l); return 0; }
C++(g++ 7.5.0) 解法, 执行用时: 3ms, 内存消耗: 476K, 提交时间: 2023-04-06 13:45:11
#include<bits/stdc++.h> using namespace std; long long t,s,x,n,m,L,R,M,D[20][10],N[20]; long long DFS(int l,int m,bool f) { if(!l)return m?1:0; if(!f&&D[l][m]!=-1)return D[l][m]; long long i,j=f?N[l]:9,S=0; for(i=0;i<=j;i++) { if(i==7)continue; S+=DFS(l-1,(m*10+i)%7,f&&i==j); } return f?S:D[l][m]=S; } long long F(long long n) { int i=1; while(n)N[i++]=n%10,n/=10; return DFS(i-1,0,1); } int main() { scanf("%lld%lld",&m,&n); memset(D,-1,sizeof(D)); L=m,R=m+n*7,s=m-F(m),x=-1; while(L<=R) { M=(L+R)>>1,t=M-F(M); if(t>=s+n)x=M,R=M-1; else L=M+1; } printf("%lld\n",x); return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 616K, 提交时间: 2019-11-05 22:13:03
#include<bits/stdc++.h> using namespace std; long long t,s,x,n,m,L,R,M,D[20][10],N[20]; long long DFS(int l,int m,bool f) { if(!l)return m?1:0; if(!f&&D[l][m]!=-1)return D[l][m]; long long i,j=f?N[l]:9,S=0; for(i=0;i<=j;i++) { if(i==7)continue; S+=DFS(l-1,(m*10+i)%7,f&&i==j); } return f?S:D[l][m]=S; } long long F(long long n) { int i=1; while(n)N[i++]=n%10,n/=10; return DFS(i-1,0,1); } int main() { scanf("%lld%lld",&m,&n); memset(D,-1,sizeof(D)); L=m,R=m+n*7,s=m-F(m),x=-1; while(L<=R) { M=(L+R)>>1,t=M-F(M); if(t>=s+n)x=M,R=M-1; else L=M+1; } printf("%lld\n",x); return 0; }