UVA493 Rational Spiral【数学模拟】

132 篇文章 1 订阅
96 篇文章 5 订阅

Rational numbers can be expressed as the division of two integers. They are also countable. This means that an order can be placed on them just like the natural numbers. But this ordering is not obvious, and is not unique. Here is one way to do it: imagine a plane where the X-axis represents the denominator of a rational number and the Y-axis represents the numerator. Starting at the origin, spiral clockwise away from it. Each integer pair that you encounter will represent a rational number. See the figure below.
在这里插入图片描述
Figure 1: Ordering of the Rational Numbers
    The first rational number that you will encounter is 0/0. But wait, this is not a rational number! Therefore, this pair must be skipped. Each time that you pass the Y-axis, the denominator will be 0, which generates an illegal rational number. You will have to skip all of these.
    You will also encounter many repeats. For example −1/1 is the same number as 1/−1. Only count the first occurance of rational numbers in the spiral. Also be aware that numbers can be reduced, which can also cause repeats. For example 8/4 reduces to 2/1, so it is a repeat. Be sure to skip all these too.
    Given these rules, you can generate an ordered listing of all the rational numbers which does not skip or repeat. Amazing, isn’t it?
    Your mission, should you choose to accept it, is to order the rational numbers.
Input
There will be several lines of input. Each line of input will have a single integer which represents which rational number to output. For example, if a line of input is 4 then print out the 4th rational number. Important, the list starts with the zeroth element.
Output
For each line of input, print out the rational number in this form: numerator, followed by a space, followed by a forward slash, followed by a space, followed by the denominator.
    Note: if the rational number is negative, the minus sign must be printed with the numerator. For example, do not print out 4/−1, print −4/1 even if you are at the (denominator == -1, numerator == 4) location on the spiral.
Sample Input
0
1
2
3
10
Sample Output
1 / 1
0 / 1
-1 / 1
-2 / 1
3 / 2

问题链接UVA493 Rational Spiral
问题简述:(略)
问题分析
    数学问题,用模拟法来解决。
程序说明:(略)
参考链接:(略)
题记:没有好方法就暴力,或者模拟。

AC的C++语言程序如下:

/* UVA493 Rational Spiral  */

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6;
vector<pair<int, int> > v;
map<int, int> m[N + 1];

void init()
{
    int cnt = 0, x = 0, y = 0, dir = 1, maxy = 0, maxx = 0, miny = 0, minx = 0;
    while(cnt < N) {
        if(x != 0 ) {
            int gcd = __gcd(abs(x), abs(y));
            int x2 = x / gcd;
            int y2 = y / gcd;
            if(x2 < 0) x2 = -x2, y2 = -y2;
            if(!m[x2].count(y2)) {
                cnt++;
                m[x2][y2] = 1;
                v.push_back(make_pair(x2, y2));
            }
         }

        if(dir == 1) {
            if(++y > maxy) {maxy = y; dir = 2;}
        } else if(dir == 2) {
            if(++x > maxx) {maxx = x; dir = 3;}
        } else if(dir == 3) {
            if(--y < miny) {miny = y; dir = 4;}
        } else if(dir == 4) {
            if(--x < minx) {minx = x; dir = 1;}
        }
    }
}

int main()
{
    init();

    int n;
    while(~scanf("%d", & n))
        printf("%d / %d\n", v[n].second, v[n].first);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值