SDNUOJ 1161.十六进制序列(找规律)

Time Limit: 1000 MS Memory Limit: 32768 KB

Description
有一个十六进制序列由S1S2…Sk组成,其中Sk由1到k的十六进制数字依次组成。给定一个位置i,返回第i个位置上的字符。
例如,S1S2…Sk的前200个字符为
112123123412345123456123456712345678123456789123456789A123456789AB123456789ABC123456789ABCD123456789ABCDE123456789ABCDEF123456789ABCDEF10123456789ABCDEF1011123456789ABCDEF101112123456789ABCDEF10111213

所以i=3时,字符为2,i=192时,字符为F。

Input
有多组输入数据,每行包含一个位置i,1<=i<=2000000000。

Output
对于每个给定的位置i,输出该位置上的字符,对于A~F字符,请输出大写字母。

Sample Input
3
192

Sample Output
2
F

要看懂序列的规律,每次每段序列中都加了一个16进制数,这一数字是上一数字加一得到的。实际上最大的问题在于如何确认n在哪一段序列中,下面的代码中我在动态更新s的同时,也在对n进行减操作,实际上就是为了确认n在哪一段序列中,如果n减到小于等于0了,说明n就在当前的s中。

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
string s;
char mi[20];
int main()
{
//	cout<<s.max_size()<<endl;//用来查看string的最大长度,是4开头的19位数 
	int n;
	while(cin>>n)
	{
		s="0";
		for(int i=1;;++i)
		{
			itoa(i,mi,16);//把当前的数变成16进制存在mi字符数组中 
			strupr(mi);//由于用函数转过来的字母是小写,用这个函数变成大写 
			s+=mi;//将mi接在s后面 
			n-=s.size()-1;//这步实际上是在确认n在哪一段序列中 
			if(n<=0)//如果n<=0说明n就在当前的序列中 
			{
				n+=s.size()-1;//让n恢复为减之前的n 
				break;
			}
		}
		cout<<s[n]<<endl;//直接用n做下标访问s即可 
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值