zoukankan      html  css  js  c++  java
  • POJ 1019 Number Sequence 解读

    这是一个看似简单,其实很难受。

    本来我想发挥它的标题轨道基础。没想到反被消遣-_-|||。

    看它在个人基础上,良好的数学就干脆点,但由于过于频繁,需求将被纳入全,因此,应该难度4星以上。

    方法就是直接打表。然后直接模拟。利用打表去掉一大段数据,剩下数据量十分小了。故此能够直接模拟。

    打表是为了计算前面的周期数,把周期数直接去掉。


    主要难点是后面10位数以上的数有2位, 3位,4位等情况要考虑。- 以下使用getNewNums一个函数攻克了,想通了,就几行代码,还不用难理解的数学计算,呵呵。

    然后是模拟数数位。那么就考主要的编程功力了。


    简洁到能够不使用不论什么数学库就0ms过的程序:

    #include <stdio.h>
    
    const int MAX_SIZE = 65535;
    long long arr[MAX_SIZE];
    
    inline int getNewNums(int i)
    {
    	int n = i;
    	for (int ten = 10; ten <= i; ten = (ten << 1) + (ten << 3))
    	{
    		n += i - ten + 1;
    	}
    	return n;
    }
    
    void fillArr()
    {
    	arr[0] = 0; arr[1] = 1; arr[2] = 3;
    	for (int i = 3; i < MAX_SIZE; i++)
    	{
    		arr[i] = arr[i-1] + getNewNums(i);
    	}
    }
    
    int getNum(int n)
    {
    	int i = 1;
    	for ( ; arr[i] < n && i < MAX_SIZE; i++);
    	n -= (int)arr[i-1];
    	int num = 1;
    	while (n)	//直接模拟,由于前面已经截去一大段数据了,所以这里能够模拟
    	{
    		char ch[33];
    		int j = 0, tmp = num;
    		while (num)
    		{
    			ch[j++] = num % 10 + '0';
    			num /= 10;
    		}
    		for (j--; j >= 0; j--)
    		{
    			if (n == 1) return ch[j] - '0';
    			n--;
    		}
    		num = tmp+1;
    	}
    	return num;	//false return.随便返回个数,上面已经会返回值了。

    } int main() { fillArr(); int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); printf("%d ", getNum(n)); } return 0; }




  • 相关阅读:
    hdu 5007 水题 (2014西安网赛A题)
    hdu 1698 线段树(成段替换 区间求和)
    poj 3468 线段树 成段增减 区间求和
    hdu 2795 公告板 (单点最值)
    UVaLive 6833 Miscalculation (表达式计算)
    UVaLive 6832 Bit String Reordering (模拟)
    CodeForces 124C Prime Permutation (数论+贪心)
    SPOJ BALNUM (数位DP)
    CodeForces 628D Magic Numbers (数位DP)
    POJ 3252 Round Numbers (数位DP)
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4583262.html
Copyright © 2011-2022 走看看