列表

详情


NC17867. 明七暗七

描述

今天是个特殊的日子,CSL和他的小伙伴们围坐在一张桌子上玩起了明七暗七的游戏。游戏规则是这样的:

一个人报出一个起始数,接下来按照逆时针的顺序轮流报数,如果碰到数是7的倍数或含有7,则拍手,下一个人接着报数。直到有一个人报错了数字或者没有及时拍手为止。

玩游戏嘛,当然得有惩罚。这么简单的游戏对CSL的学霸小伙伴而言实在是太无脑了,轻轻松松数到上万根本不在话下。但是对于数学是体育老师教的CSL来说,实在是太难了。快帮他算算什么时候应该拍手吧。

输入描述

输入两个整数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;
}

上一题