题目描述现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张表来证明这一命题的:
1/1 , 1/2 , 1/3, 1/4, 1/5, …
2/1, 2/2, 2/3, 2/4, …
3/1 , 3/2, 3/3, …
4/1, 4/2, …
5/1, ……
我们以Z字形给上表的每一项编号。第一项是1/1,然后是1/2,2/1,3/1,2/2,…
输入输出格式
输入格式:
整数N(1≤N≤10000000)
输出格式:
表中的第N项
输入输出样例
输入样例#1:
7
输出样例#1:
1/4
模拟了半天才发现没必要递归,写的有些麻烦了。
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int a = 1, b = 1, cnt = 1, c = 1;//a为分子,b为分母,cnt记录层数,c为编号
int main()
{
cin >> n;
while(1)
{
if (c == n)//编号和n相等时输出
{
cout << a << "/" << b << endl;
break;
}
if (a == 1)//如果到达第一行边界处
{
if (b % 2)//如果是奇数列
b++, cnt++, c++;//向下走,层数加一
else
a++, b--, c++;//否则向左下方走
}
else if (b == 1)//若到达第一列边界处
{
if (a % 2)//如果行是奇数行
a--, b++, c++;//向右上方走
else
a++, cnt++, c++;//否则向右走,层数加一
}
else if (cnt % 2)//如果不在边界处,若层数为奇数
{
a--, b++, c++;//向右上方走
}
else
a++, b--, c++;//否则向左下方走
}
//system("pause");
return 0;
}
大佬的简便方法:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n, cnt = 0, sum = 0;//cnt计算行层,sum计算每行结束时编号最大的值
cin >> n;
while (sum < n)//编号没到n时继续
{
cnt++;//层数加一
sum += cnt;//每层编号最大值加层数
}
if (cnt % 2)//奇数层
cout << sum - n + 1 << "/" << cnt - sum + n << endl; //最大值-n+1 / 层数-最大值+n
else//偶数层
cout << cnt - sum + n << "/" << sum - n + 1 << endl;//反过来
//system("pause");
return 0;
}