zoukankan      html  css  js  c++  java
  • 【POJ3208】Apocalypse Someday(数位DP)

    Description
    666号被认为是神秘的“野兽之数”,在所有以启示录为主题的大片中都是一个被广泛使用的数字。但是,这个数字666不能总是在脚本中使用,所以应该使用1666这样的数字。让我们把至少包含三个连续的六位数字的数字称为可怕的数字。头几个可怕的数字是666,1666,2666,3666,4666,5666…

    给定一个基于1的索引n,程序应该返回第n个可怕的数字。
    Input
    第一行包含测试用例的数量t(t≤1000)。

    以下每一个t行包含一个整数n(1≤n≤50000000)作为测试用例。

    Output
    对于每个测试用例,您的程序应该输出第n个糟糕的数字。
    Sample Input
    3
    2
    3
    187
    Sample Output
    1666
    2666
    66666

    这题的(T)比较小,我们考虑二分第(n)个可怕的数。

    数位DP求出这个数字之前有几个可怕的数。

    #include<bits/stdc++.h>
    using namespace std;
    int dp[101][2][2][2],n,x,a[101],cnt,t;
    int get_ans(int wei,int st,int nd,int six,int ding)
    {
    	if(!wei)
    	{
    		return six;
    	}
    	if(!ding&&dp[wei][st][nd][six])
    	{
    		return dp[wei][st][nd][six];
    	}
    	int up=ding?a[wei]:9,ans=0;
    	for(int i=0;i<=up;i++)
    	{
    		if(six)
    		{
    			ans+=get_ans(wei-1,i==6,st,1,ding&&(i==up));
    		}else{
    			ans+=get_ans(wei-1,i==6,st,st&&nd&&i==6,ding&&(i==up));
    		}
    	}
    	if(!ding)
    	{
    		dp[wei][st][nd][six]=ans;
    	}
    	return ans;
    }
    int check(long long x)
    {
    	cnt=0;
    	while(x)
    	{
    		a[++cnt]=x%10;
    		x/=10;
    	}
    	return get_ans(cnt,0,0,0,1);
    }
    int main()
    {
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&x);
    		long long l=1,r=100000000000;
    		while(l<=r)
    		{
    			long long mid=(l+r)/2;
    			if(check(mid)<x)
    			{
    				l=mid+1;
    			}else{
    				r=mid-1;
    			}
    		}
    		printf("%lld
    ",l);
    	}
    	return 0;
    }
    
  • 相关阅读:
    android http通信——HttpURLConntection
    Android UI设计秘笈
    android文字滚动
    android半透叠加对照表
    gcc编译问题记录
    安装AIX补丁集
    php安装过程记录
    参加计算机大会了
    Linux平台mysql的安装配置
    oracle 故障案例排查
  • 原文地址:https://www.cnblogs.com/2017gdgzoi44/p/11558889.html
Copyright © 2011-2022 走看看