poj1019
2013-04-26 22:17
211 查看
本文问题分析参考http://blog.csdn.net/lyy289065406/article/details/6648504
大致题意:
有一串数字串,其规律为
1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 123456789101112······k
输入位置n,计算这一串数字第n位是什么数字,注意是数字,不是数!例如12345678910的第10位是1,而不是10,第11位是0,也不是10。总之多位的数在序列中要被拆分为几位数字,一个数字对应一位。
解题思路:
首先建议数学底子不好的同学,暂时放一放这题,太过技巧性了,连理解都很困难
模拟分组,把1看做第1组,12看做第2组,123看做第3组……那么第i组就是存放数字序列为 [1,i]的正整数,但第i组的长度不一定是i
已知输入查找第n个位的n的范围为(1 ≤ n ≤ 2147483647),那么至少要有31268个组才能使得数字序列达到有第2147483647位
注意:2147483647刚好是int的正整数最大极限值( ),所以对于n用int定义就足矣。但是s[31268]存在超过2147483647的位数,因此要用unsigned 或long 之类的去定义s[]
详细的解题思路请参照程序的注释。
其中数学难点有2:
(int)log10((double)i)+1
(i-1)/(int)pow((double)10,len-pos)%10
非常技巧性的处理手法,其意义已在程序中标明
//* @author:
//方法一:
/**
* 有一串数字串,其规律为:11212312341234512345612345671234567812345678912345678910123456789101112345678910······
输入位置,输出对应位置的数字,
如:输入8,输出2;输入:56,输出0,
注意:两位数字、三位数字对应位都是分开的,难度在这里,输入范围是
其主要算法如下:
父数字串------>>子数字串-------->>最简数字串
*/
public class Main {
/**
* 求数 n 的位数,如:
* 12的位数为2,100的位数为3,,5的位数为1
* @param n
* @return
*/
public static int getWeiShu(int n) {
int weiShu = 0;
while (n != 0) {
n = n / 10;
weiShu++;
}
return weiShu;
}
public static int location(int i) {
// i - 所求序数
// ans - 所求位的数字
// j - 递推定位串
// base - 记录每个串递增的位数
// sum - 记录串的总位数 、 用作计数
int ans;
int j = 1, base, sum = 1;
while (i >= sum) {//如果所求的位置大于数字串的总位数
//将所求的序数减去某一个串的总位数
i -= sum;
j++; // j 记载 下一个串 到哪个数字串了 -- 12...j
//获取某一个数字串的位数
base = getWeiShu(j);
// 该串比上一个串多的字符数 - j 的位数
//其实是某一个数字串的位数如112123,sum在这里表示的是数字串1
//或数字串12,或数字串123的位数
sum += base; // 该串的字符总数
}
// 出口:i >= 0
/**
* 当序数i恰好到某一个数字串就结束了
*/
if (i == 0) {
ans = (j - 1) % 10;
return ans;
}
/**
* 以上代码应该是实现了将i定位到某一个数字串的功能,
* 例如,从112123123412345中找出了i在12345中
*
*/
sum = 1; // 从串(1...j) 中第一个数开始找
base = 1; // 串中第一个数的位数是 1
while (i >= base) // 求 1...j 串中第 i 个数字
{
i -= base;
sum++;
//base用来记录当前遍历到数组的位数
base = getWeiShu(sum); // sum 的位数
}
/**
* if语句主要用于处理这是已经是没有字数字串的情况
* 即,在12345中找到了某一个数字,或1,或2,或3,
*/
if (i == 0) {
ans = (sum - 1) % 10;
return ans;
}
/**
* 以下代码主要处理:
* 在小字符串中如123456789101112131415中
* 的12中确定到底是哪一个数字
*
* 对于以下求i的算法,理解如下:
*
*
*对于123456789(不可能为1234567891011···,此时的数字串已经为最简数字串,不可能在包含子数字串),
*加入我们要取5,我们通常习惯于%10,-----(但是%10时,我们取的是个位)--------->>所以得把
*5以后的数字都去掉,-----(这时我们习惯采取/10操作)-------->>/10的次数由getWeiShu(sum)-i来决定
*/
j = getWeiShu(sum) - i;
while (j-- > 0) // ans is the ith number of (sum)
{
sum /= 10;
}
ans = sum % 10;
return ans;
}
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
int t = input.nextInt(); // test number,测试用例的个数
while (t-- > 0) {
//要求位置的数字
int i = input.nextInt();
System.out.println(location(i));
}
}
}
大致题意:
有一串数字串,其规律为
1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 123456789101112······k
输入位置n,计算这一串数字第n位是什么数字,注意是数字,不是数!例如12345678910的第10位是1,而不是10,第11位是0,也不是10。总之多位的数在序列中要被拆分为几位数字,一个数字对应一位。
解题思路:
首先建议数学底子不好的同学,暂时放一放这题,太过技巧性了,连理解都很困难
模拟分组,把1看做第1组,12看做第2组,123看做第3组……那么第i组就是存放数字序列为 [1,i]的正整数,但第i组的长度不一定是i
已知输入查找第n个位的n的范围为(1 ≤ n ≤ 2147483647),那么至少要有31268个组才能使得数字序列达到有第2147483647位
注意:2147483647刚好是int的正整数最大极限值( ),所以对于n用int定义就足矣。但是s[31268]存在超过2147483647的位数,因此要用unsigned 或long 之类的去定义s[]
详细的解题思路请参照程序的注释。
其中数学难点有2:
(int)log10((double)i)+1
(i-1)/(int)pow((double)10,len-pos)%10
非常技巧性的处理手法,其意义已在程序中标明
//* @author:
//方法一:
/**
* 有一串数字串,其规律为:11212312341234512345612345671234567812345678912345678910123456789101112345678910······
输入位置,输出对应位置的数字,
如:输入8,输出2;输入:56,输出0,
注意:两位数字、三位数字对应位都是分开的,难度在这里,输入范围是
其主要算法如下:
父数字串------>>子数字串-------->>最简数字串
*/
public class Main {
/**
* 求数 n 的位数,如:
* 12的位数为2,100的位数为3,,5的位数为1
* @param n
* @return
*/
public static int getWeiShu(int n) {
int weiShu = 0;
while (n != 0) {
n = n / 10;
weiShu++;
}
return weiShu;
}
public static int location(int i) {
// i - 所求序数
// ans - 所求位的数字
// j - 递推定位串
// base - 记录每个串递增的位数
// sum - 记录串的总位数 、 用作计数
int ans;
int j = 1, base, sum = 1;
while (i >= sum) {//如果所求的位置大于数字串的总位数
//将所求的序数减去某一个串的总位数
i -= sum;
j++; // j 记载 下一个串 到哪个数字串了 -- 12...j
//获取某一个数字串的位数
base = getWeiShu(j);
// 该串比上一个串多的字符数 - j 的位数
//其实是某一个数字串的位数如112123,sum在这里表示的是数字串1
//或数字串12,或数字串123的位数
sum += base; // 该串的字符总数
}
// 出口:i >= 0
/**
* 当序数i恰好到某一个数字串就结束了
*/
if (i == 0) {
ans = (j - 1) % 10;
return ans;
}
/**
* 以上代码应该是实现了将i定位到某一个数字串的功能,
* 例如,从112123123412345中找出了i在12345中
*
*/
sum = 1; // 从串(1...j) 中第一个数开始找
base = 1; // 串中第一个数的位数是 1
while (i >= base) // 求 1...j 串中第 i 个数字
{
i -= base;
sum++;
//base用来记录当前遍历到数组的位数
base = getWeiShu(sum); // sum 的位数
}
/**
* if语句主要用于处理这是已经是没有字数字串的情况
* 即,在12345中找到了某一个数字,或1,或2,或3,
*/
if (i == 0) {
ans = (sum - 1) % 10;
return ans;
}
/**
* 以下代码主要处理:
* 在小字符串中如123456789101112131415中
* 的12中确定到底是哪一个数字
*
* 对于以下求i的算法,理解如下:
*
*
*对于123456789(不可能为1234567891011···,此时的数字串已经为最简数字串,不可能在包含子数字串),
*加入我们要取5,我们通常习惯于%10,-----(但是%10时,我们取的是个位)--------->>所以得把
*5以后的数字都去掉,-----(这时我们习惯采取/10操作)-------->>/10的次数由getWeiShu(sum)-i来决定
*/
j = getWeiShu(sum) - i;
while (j-- > 0) // ans is the ith number of (sum)
{
sum /= 10;
}
ans = sum % 10;
return ans;
}
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
int t = input.nextInt(); // test number,测试用例的个数
while (t-- > 0) {
//要求位置的数字
int i = input.nextInt();
System.out.println(location(i));
}
}
}
相关文章推荐
- poj1019
- poj 1019 Number Sequence
- POJ 1019 Number Sequence (数学+预处理 循环递增序列第k位数字)
- POJ 1019:Number Sequence
- [POJ][1019]Number Sequence
- poj 1019 Number Sequence
- POJ1019:Number Sequence
- POJ 1019 Number Sequence (规律题)
- acm之poj题库1019方法
- POJ1019:Number Sequence
- poj 1019
- poj1019_Number_Sequence
- poj 1019 Number Sequence , 二分
- POJ 1019:Number Sequence
- POJ_1019_Number Sequence
- POj 1019 number sequence(数学)
- poj 1019 (数学计算)
- POJ 1019 组合计数
- POJ 1019 Number Sequence
- poj 1019 Number Sequence