Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595

Пересечение двух окружностей

11.05.2013, 22:57. Показов 4105. Ответов 10

Студворк — интернет-сервис помощи студентам
Есть такая задачка.

Вам даны две окружности в плоскости. Найдите все их различные точки пересечения.

В силу большой требуемой точности рекомендуется использовать более чем 8-байтные вещественнозначные типы при вычислениях. Вот тут сразу вопрос, это какие типы ? double 8 байтный, больше не знаю. Пишу на MVSC++ 2012

Входные данные
В первой строке M (1 <= M <= 10000) -- количество тестов. Следующие 2M строк описывают сами окружности. Каждая окружность описывается 3 числами: координатами центра и радиусом.
Все числа в файле целые, известно, что все координаты от -1000 до +1000, и радиус больше нуля и не превосходит 1000.

Выходные данные
Для каждого теста выведите сообщение:
There are no points!!! -- если нет точек пересечения;
There are only i of them.... -- если есть только i точек пересечения. Выведите в след. i строках сами точки, сортируя их по x в первую очередь и по y во вторую. Выводите их с 12 знаками после запятой.
I can't count them - too many points -- если их бесконечное число.
Разделяйте выводы для разных тестов пустой строкой.

Пример

Ввод
1
0 0 2
4 0 2
Вывод
There are only 1 of them....
2.00000000000000 0.00000000000000

Решал так :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <set>
#include <vector>
#include <limits>
#include <stdio.h>
#include <string>
#include <queue>
#include <time.h>
 
using namespace std;
 
double eps = 1e-18;
 
bool comp(long double a, long double b){
    return (abs(a-b) < eps);
} 
 
void circle_line(long double a, long double b, long double c, long double r, long double x1, long double y1){
    long double x0 = -a*c/(a*a+b*b);
    long double y0 = -b*c/(a*a+b*b);
    if (c*c > r*r*(a*a+b*b)+eps){
        printf("There are no points!!!\n");
    }else if (comp(c*c, r*r*(a*a+b*b))) {
        printf("There are only 1 of them....\n");
        printf("%.14lf %.14lf\n", x0 + x1, y0 + y1);
    } else {
        printf("There are only 2 of them....\n");
        long double d = r*r - c*c/(a*a+b*b);
        long double mult = sqrt (d / (a*a+b*b));
        long double ax = x0 + b * mult;
        long double bx = x0 - b * mult;
        long double ay = y0 - a * mult;
        long double by = y0 + a * mult;
        if (ax > bx || (ax == bx && ay > by)) {
            swap(ax, bx);
            swap(ay, by);
        }
        printf("%.14lf %.14lf\n%.14lf %.14lf\n", ax + x1, ay + y1, bx + x1, by + y1);
    }
}
 
void circle_circle (long double x1, long double y1, long double r1, long double x2, long double y2, long double r2){
    if (comp(x1, x2) && comp(y1, y2)) {
        if (!comp(r1, r2)){
            printf("There are no points!!!\n");
        } else {
            printf("I can't count them - too many points :(\n");
        }
        return;
    }
    x2 -= x1;
    y2 -= y1;
    circle_line(- 2.0 * x2, - 2.0 * y2, x2*x2 + y2*y2 + r1*r1 - r2*r2, r1, x1, y1);
}
 
int main() {
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
    int t;
    cin >> t;
    while (t > 0) {
        long double x1, y1, r1, x2, y2, r2;
        scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &r1, &x2, &y2, &r2);
        circle_circle(x1, y1, r1, x2, y2, r2);
        printf("\n");
        t--;
    }
    return 0;
}
(Доступ к контестору только из Саратова http://acm.sgu.ru/univer/)

Добавлено через 39 секунд
В чём ошибка ?

Добавлено через 50 секунд
http://e-maxx.ru/algo/circles_intersection можно руководствоваться

Добавлено через 3 минуты
статус :
Test.1: OK with Time 0 ms
Test.2: OK with Time 0 ms
Test.3: OK with Time 0 ms
Test.4: OK with Time 15 ms
Test.5: OK with Time 0 ms
Test.6: WA with Time 31 ms
Test.7: WA with Time 31 ms
Test.8: OK with Time 62 ms
Test.9: OK with Time 31 ms
Test.10: OK with Time 62 ms
Test.11: OK with Time 62 ms
Test.12: OK with Time 62 ms
Test.13: WA with Time 62 ms
Test.14: WA with Time 46 ms
Test.15: WA with Time 78 ms
Test.16: WA with Time 0 ms
Test.17: OK with Time 15 ms
Test.18: WA with Time 15 ms
Test.19: OK with Time 15 ms

Добавлено через 5 минут
Мне кажется потеря точности

Добавлено через 47 минут
upup

Добавлено через 4 часа 16 минут
upb

Добавлено через 2 часа 28 минут
апп
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.05.2013, 22:57
Ответы с готовыми решениями:

Пересечение двух окружностей
На плоскости даны две окружности. Требуется проверить, пересекаются ли они. Входные данные Входной файл INPUT.TXT состоит из двух...

Задача на пересечение двух окружностей
Всем привет! Прошу вашей помощи в решении задачи так как я уже дней пять над ней мучаюсь и все не выходит. Даны две окружности в...

Пересечение двух прямых и проверка на пересечение
Доброго времени суток слизал функцию проверки отсюда:/segments_intersection_checking на всякий случай у меня она выглядит так: int...

10
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
11.05.2013, 23:04
...

Добавлено через 1 минуту
Цитата Сообщение от Ternsip Посмотреть сообщение
Вот тут сразу вопрос, это какие типы ? double 8 байтный, больше не знаю. Пишу на MVSC++ 2012
Ты же используешь long double !?
0
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
11.05.2013, 23:54  [ТС]
lazybiz, а он в MVSC++ 2012 ничем не отличается от double
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
12.05.2013, 00:08
Если в контестере используется MSVS тогда я хз..
Может дело не в точности?
0
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
12.05.2013, 12:50  [ТС]
lazybiz, может

Добавлено через 11 часов 51 минуту
upup

Добавлено через 48 минут
апь
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
12.05.2013, 14:37
Пока вижу только, что надо 12 знаков после запятой, а выводится 14. Из-за этого может не совпасть с ответом в младших цифрах (да и вообще это формат вывода, не удовлетворяющий условию, так что можно бы было сразу везде WA засчитывать).

Добавлено через 3 минуты
C++
1
if (ax > bx || (ax == bx && ay > by)) {
Тут сравнения без eps.
1
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
13.05.2013, 09:18  [ТС]
Somebody, на 1 WA больше
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <set>
#include <vector>
#include <limits>
#include <stdio.h>
#include <string>
#include <queue>
#include <time.h>
 
using namespace std;
 
double eps = 1e-18;
 
bool comp(long double a, long double b){
    return (abs(a-b) < eps);
} 
 
void circle_line(long double a, long double b, long double c, long double r, long double x1, long double y1){
    long double x0 = -a*c/(a*a+b*b);
    long double y0 = -b*c/(a*a+b*b);
    if (c*c > r*r*(a*a+b*b)+eps){
        printf("There are no points!!!\n");
    }else if (comp(c*c, r*r*(a*a+b*b))) {
        printf("There are only 1 of them....\n");
        printf("%.12lf %.12lf\n", x0 + x1, y0 + y1);
    } else {
        printf("There are only 2 of them....\n");
        long double d = r*r - c*c/(a*a+b*b);
        long double mult = sqrt (d / (a*a+b*b));
        long double ax = x0 + b * mult;
        long double bx = x0 - b * mult;
        long double ay = y0 - a * mult;
        long double by = y0 + a * mult;
        if (ax > bx || (comp(ax, bx) && ay > by)) {
            swap(ax, bx);
            swap(ay, by);
        }
        printf("%.12lf %.12lf\n%.12lf %.12lf\n", ax + x1, ay + y1, bx + x1, by + y1);
    }
}
 
void circle_circle (long double x1, long double y1, long double r1, long double x2, long double y2, long double r2){
    if (comp(x1, x2) && comp(y1, y2)) {
        if (!comp(r1, r2)){
            printf("There are no points!!!\n");
        } else {
            printf("I can't count them - too many points :(\n");
        }
        return;
    }
    x2 -= x1;
    y2 -= y1;
    circle_line(- 2.0 * x2, - 2.0 * y2, x2*x2 + y2*y2 + r1*r1 - r2*r2, r1, x1, y1);
}
 
int main() {
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
    int t;
    cin >> t;
    while (t > 0) {
        long double x1, y1, r1, x2, y2, r2;
        scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &r1, &x2, &y2, &r2);
        circle_circle(x1, y1, r1, x2, y2, r2);
        printf("\n");
        t--;
    }
    return 0;
}
Добавлено через 2 минуты
Somebody, а вот если ставлю %.15lf везде то по-прежнему 12 тестов, (на %.12lf было 11)

Добавлено через 18 часов 30 минут
Help
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
13.05.2013, 09:41
А зачем ты сам определяешь EPSILON: double eps = 1e-18; ?
Он определен в float.h, и у меня в GCC 4.7.3 он равен другому числу: 2.22045e-016
0
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
13.05.2013, 15:55  [ТС]
lazybiz, мне так удобней, сути это не меняет. ошибка не в этом

Добавлено через 3 часа 47 минут
help

Добавлено через 41 секунду
Должен же быть какой то способ избавления от переполнения !!
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
13.05.2013, 17:05
Универсальный и надёжный способ - сделать самому всю математику. Мантисса, порядок, все арифметические действия. Вопрос только в том, действительно ли задача тут на эту тему или просто ошибка в алгоритме, из-за которой где-то какие-то погрешности.
1
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
13.05.2013, 17:21  [ТС]
Somebody, Забавное предложение, учту его, спасибо и на этом. Только я назвал бы это арифметикой, а задача исключительно на геометрию и не должна вызывать никаких сложностей в написании на с++, связанных с другими темами.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.05.2013, 17:21
Помогаю со студенческими работами здесь

Столкновение двух окружностей
Итак,я сталкиваю два шарика(но вообще их больше,массив). Какое-то время после старта программы все нормально,однако спустя некоторое...

Координаты пересечения двух окружностей
На вход даются целочисленные координаты двух окружностей и целочисленные их радиусы, которые не меньше 1 и не больше, чем 1000. Они...

Строка: Добавить в строковый класс функцию, которая создает строку, содержащую пересечение двух строк, то есть общие символы для двух строк.
Добавить в строковый класс функцию, которая создает строку, содержащую пересечение двух строк, то есть общие символы для двух строк....

Вычислить площадь пересечения двух окружностей
Здравствуйте) Может кто-нибудь сталкивался с написнием программы для вычисления площади пересечения двух кругов? помогите, пожалуйста...

Вводится значение двух радиусов окружностей
Помогите создать блок схему для задачи c пояснениями пожалуйста: Вводится значение двух радиусов окружностей R1,R2 и координаты точки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru