Форум программистов, компьютерный форум CyberForum.ru

Определить количество пораженных мишеней - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
Temirlan90
 Аватар для Temirlan90
131 / 131 / 8
Регистрация: 30.09.2010
Сообщений: 333
12.05.2011, 17:48     Определить количество пораженных мишеней #1
Кликните здесь для просмотра всего текста
Биатлон
(Время: 1 сек. Память: 16 Мб Сложность: 24%)

На Зимних Олимпийских Играх традиционно проводятся соревнования по биатлону. Как известно, этот вид спорта содержит лыжные гонки и стрельбу по мишеням из винтовки. На каждом огневом рубеже расположены 5 мишеней. Каждая из них имеет форму круга радиусом 10 см, а расстояния между центрами соседних мишеней одинаковы и равны 25 см. Центры мишеней при этом расположены на одной горизонтали.

Введем прямоугольную систему координат так, что начало координат расположено в центре самой левой мишени, ось Ox направлена вправо, а ось Oy - вверх. Таким образом, центры мишеней имеют координаты (0, 0), (25, 0), (50, 0), (75, 0) и (100, 0).

Для информационного обеспечения проведения соревнований было решено разработать систему подсчета количества пораженных мишеней. Эта система по точкам, в которые попали пули после выстрелов спортсмена, должна определять количество пораженных мишеней. Мишень считается пораженной, если в нее попала хотя бы одна пуля (при этом, разумеется, если в мишень попали две или больше пуль, то попадание считается только один раз).

На спринтерской гонке на каждом огневом рубеже у спортсмена есть 5 пуль. Вам даны координаты точек, в которые попали пули после выстрелов спортсмена. Определите количество пораженных мишеней.
Входные данные

Входной файл INPUT.TXT содержит ровно пять строк: i-ая из них содержит два целых числа xi и yi - координаты точки, в которую попала пуля после i-ого выстрела спортсмена. Все числа во входном файле не превосходят 1000 по модулю.
Выходные данные

В выходной файл OUTPUT.TXT выведите единственное число – число пораженных мишеней.
INPUT.TXT
0 0
25 0
50 0
75 0
100 0
OUTPUT.TXT
5

INPUT.TXT
0 0
0 0
0 0
75 0
100 0
OUTPUT.TXT
3

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
#include <iostream>
using namespace std;
int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int x, y, count = 0, t1, t2, t3, t4, t5;
    t1 = t2 = t3 = t4 = t5 = 0;
    for(int i = 0; i < 5; ++i) {
        cin >> x >> y;
        if(abs(x) + abs(y) >= 0 && abs(x) + abs(y) <= 10 && t1 != 1) {
            t1 = 1;
            ++count;
        }
        else if(abs(x) + abs(y) >= 15 && abs(x) + abs(y) <= 35 && t2 != 1) {
            t2 = 1;
            ++count;
        }
        else if(abs(x) + abs(y) >= 40 && abs(x) + abs(y) <= 60 && t3 != 1) {
            t3 = 1;
            ++count;
        }
        else if(abs(x) + abs(y) >= 65 && abs(x) + abs(y) <= 85 && t4 != 1) {
            t4 = 1;
            ++count;
        }
        else if(abs(x) + abs(y) >= 90 && abs(x) + abs(y) <= 110 && t5 != 1) {
            t5 = 1;
            ++count;
        }
    }
    cout << count;  
    return 0;
}
7-й тест проваливает..., дайте контр-пример.

Добавлено через 1 час 42 минуты
контр-пример
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.05.2011, 17:48     Определить количество пораженных мишеней
Посмотрите здесь:

В массиве А(n) (n<=7) хотя бы один нуль. Определить количество положительных и количество отрицательных элементов к первому нулю. C++
C++ Определить количество выигрышей, количество проигрышей и количество ничьих данной команды
В массиве записаны результаты N игр футбольной команды. Определить количество выигрышей, количество проигрышей и количество ничьих данной команды. C++
Определить количество положительных и количество отрицательных элементов массива C++
C++ Определить количество положительных и количество отрицательных элементов до первого нуля. Найти ошибку в коде
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
x1Mike7x
 Аватар для x1Mike7x
214 / 127 / 6
Регистрация: 06.11.2010
Сообщений: 234
12.05.2011, 17:49     Определить количество пораженных мишеней #2
А почему все проверки координат производятся по модулю?
Что, если во входном потоке данные (-25; 0), что = промаху, а засчитается как (25; 0)
Temirlan90
 Аватар для Temirlan90
131 / 131 / 8
Регистрация: 30.09.2010
Сообщений: 333
12.05.2011, 18:01  [ТС]     Определить количество пораженных мишеней #3
x1Mike7x, если у "х" убрать abs, то 4 тест проваливает
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
12.05.2011, 18:55     Определить количество пораженных мишеней #4
Temirlan90, Условия никуда не годятся:
(Для 1-го нормально), а для остальных:
Цитата Сообщение от Temirlan90 Посмотреть сообщение
else if(abs(x) + abs(y) >= 15 && abs(x) + abs(y) <= 35 && t2 != 1) {
t2 = 1;
++count;
}
например x=-20 y=-10
получится что 2-ая мишень поражена.
Попробуйте добавить еще к остальным (кроме первого условия) что x>0
x1Mike7x
 Аватар для x1Mike7x
214 / 127 / 6
Регистрация: 06.11.2010
Сообщений: 234
12.05.2011, 19:05     Определить количество пораженных мишеней #5
В принципе да, оно по-любому завалится... =)
Условие проверки должно быть другое. А именно:
1) Вводятся координаты точки куда попали
2) Проверяем для каждого центра мишени расстояние от центра к точке попадания
C++
1
R = sqrt( (X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1) )
3) Если R <= 10, тогда записываем для этой мишени попадание

Выйдет что-то типа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for ( i = 0; i < 5; ++i )
{
    cin >> X >> Y;
    for ( j = 0; j < 101; j += 25 )
    {
        R = sqrt( (X - j) * (X - j) + (Y - 0) * (Y - 0) );
        if ( R <= 10 )
        {
            used[ j / 25 ] = 1;
            break;
        }
    }
}
for ( i = 0; i < 5; ++i )
    K += used[i];
cout << K;

Вот, кстати, контр-пример:
Х = 13
Y = 3
Должен быть промах.
Temirlan90
 Аватар для Temirlan90
131 / 131 / 8
Регистрация: 30.09.2010
Сообщений: 333
14.05.2011, 11:06  [ТС]     Определить количество пораженных мишеней #6
valeriikozlov, Добавил условие, все равно 7 тест проваливает.
x1Mike7x, в Вашем примере
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
#include <iostream>
#include <cmath>
using namespace std;
int main() {
    float R, X, Y;
    int used[100], K = 0;
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    for (int i = 0; i < 5; ++i) {
        cin >> X >> Y;
        for (int j = 0; j < 101; j += 25) {
            R = sqrt((X - j) * (X - j) + (Y - 0) * (Y - 0));
            if (R <= 10) {
                used[j / 25] = 1;
                break;
            }
        }
    }
    for (int i = 0; i < 5; ++i)
        K += used[i];
    cout << K;
    /*system("pause >> void");*/
    return 0;
}
при 2 тесте ответ выдает -1717986917 О_о
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
14.05.2011, 12:38     Определить количество пораженных мишеней #7
Ваша ошибка в слишком правильном понимании условия. Там никакая не окружность, а всего-лишь квадрат.
Решается "в лоб"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <map>
short is(int x, int y){
    if (y>11||y<-11) return 0;
    if (x>-11&&x<11) return 1;
    if (x>14&&x<36) return 2;
    if (x>39&&x<61) return 3;
    if (x>64&&x<86) return 4;
    if (x>89&&x<111) return 5;
    return 0;
}
int main(){
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    int x,y,i=5;
    std::map<int,int> m;
    while (i--){
        std::cin >> x >> y;
        if (is(x,y)) m[is(x,y)]++;
    }
    std::cout << m.size();
    return 0;
}
x1Mike7x
 Аватар для x1Mike7x
214 / 127 / 6
Регистрация: 06.11.2010
Сообщений: 234
14.05.2011, 16:50     Определить количество пораженных мишеней #8
Ошибка на 2м тесте из-за отсутствия зануления массива.
Вот так должно быть.
C
1
int used[5] = {};
И, к тому же, массив на 100 элементов не нужен, в цикле мы же делим j на 25 (т.е. никогда индекс больше 100/25 = 4 не получится) при записи единицы.
P.S. И там таки круг, а не квадрат.
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
14.05.2011, 16:51     Определить количество пораженных мишеней #9
Неет... Поверьте мне как человеку, сдавшему эту задачу(решение в 7 посте под катом, проходит все тесты)
Всего лишь неверное условие, тоже бывает. В биатлоне, кстати, нельзя попасть два раза в одну и ту же мишень, т.к. после попадания ее уже и нету...
Live4Sky
6 / 1 / 1
Регистрация: 04.10.2013
Сообщений: 42
03.02.2014, 13:55     Определить количество пораженных мишеней #10
Цитата Сообщение от x1Mike7x Посмотреть сообщение
Ошибка на 2м тесте из-за отсутствия зануления массива.
Вот так должно быть.
C
1
int used[5] = {};
И, к тому же, массив на 100 элементов не нужен, в цикле мы же делим j на 25 (т.е. никогда индекс больше 100/25 = 4 не получится) при записи единицы.
P.S. И там таки круг, а не квадрат.
Решил по вашем способу,не знаю какие там квадраты...в общем вот код все работает
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
#include <fstream>
#include <cmath>
using namespace std;
int main() {
    float radius,x, y;
    int used[100]={};
    int count=0;
    ifstream cin("input.txt");
    ofstream cout("output.txt");
    for (int i = 0; i<5; i++) {
        cin>>x>>y;
        for (int j = 0; j <= 100; j += 25) {
            radius = sqrt((x - j) * (x - j) + (y - 0) * (y - 0));
            if (radius <= 10) {
                used[j / 25] = 1;
                break;
            }
        }
    }
    for (int i = 0; i < 5; ++i){
        count+=used[i];
    }
    cout<<count;
 
}
Добавлено через 19 минут
Цитата Сообщение от Live4Sky Посмотреть сообщение
Решил по вашем способу,не знаю какие там квадраты...в общем вот код все работает
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
#include <fstream>
#include <cmath>
using namespace std;
int main() {
    float radius,x, y;
    int used[100]={};
    int count=0;
    ifstream cin("input.txt");
    ofstream cout("output.txt");
    for (int i = 0; i<5; i++) {
        cin>>x>>y;
        for (int j = 0; j <= 100; j += 25) {
            radius = sqrt((x - j) * (x - j) + (y - 0) * (y - 0));
            if (radius <= 10) {
                used[j / 25] = 1;
                break;
            }
        }
    }
    for (int i = 0; i < 5; ++i){
        count+=used[i];
    }
    cout<<count;
 
}
только одного не пойму зачем used[j / 25] = 1;
Melvil
 Аватар для Melvil
47 / 46 / 13
Регистрация: 20.05.2015
Сообщений: 246
04.07.2015, 13:48     Определить количество пораженных мишеней #11
Фух, сидел разбирался столько времени, наконец, могу с уверенностью предложить кратчайший вариант решения задачи с пояснением. Проходит все тесты.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <cmath> // Для работы sqrt 
#include <iostream>
using namespace std;
void main()
{
    int counter = 0; // Счётчик
    double R, x, y; // Объявление переменных типа double, дабы работало sqrt.
    int used[5] = {}; // Создание массива, который полон нулей.
    for (int j = 0; j < 101; j += 25) // Счётчик. Во-первых отсчитывает 5 мишеней. Во-вторых, служит индикатором заполненности массива.
    // В третьих,  дальностью радиуса мишеней.
    {
        cin >> x >> y; // Ввод кординат
        R = sqrt((x - j)*(x - j) + (y - 0) * (y - 0)); // Считаем расстояние от точки до центра мишени
        if (R <= 10) // Если точка в зоне радиуса
        used[j / 25] = 1; // Заполняем элемент массива
    }
    for (int i = 0; i < 5; i++) // Заполнение "главного" счётчика
    {
        counter += used[i]; // Собираем все единицы из массива
    }
    cout << counter << endl; // Вывод.
}
Melvil
 Аватар для Melvil
47 / 46 / 13
Регистрация: 20.05.2015
Сообщений: 246
05.07.2015, 20:00     Определить количество пораженных мишеней #12
Пожалуй самое короткое решение:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cmath>
#include <iostream>
using namespace std;
void main()
{
    int counter = 0;
    double R, x, y;
    for (int j = 0; j < 101; j += 25)
    {
        cin >> x >> y;
        R = sqrt((x - j)*(x - j) + (y - 0) * (y - 0));
        if (R <= 10)
            counter += 1;
    }
    cout << counter;
}
P.S.

Первое место по скорости, памяти и размеру среди всех прочих решений.
Fulcrum_013
 Аватар для Fulcrum_013
393 / 566 / 60
Регистрация: 14.12.2014
Сообщений: 4,769
Завершенные тесты: 2
05.07.2015, 22:41     Определить количество пораженных мишеней #13
Цитата Сообщение от Melvil Посмотреть сообщение
Первое место по скорости, памяти и размеру среди всех прочих решений.
Можно гораздо быстрее
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
05.07.2015, 22:45     Определить количество пораженных мишеней #14
Цитата Сообщение от Melvil Посмотреть сообщение
Фух, сидел разбирался столько времени
4 года? Поздравляю.
IrineK
Заблокирован
05.07.2015, 23:05     Определить количество пораженных мишеней #15
Цитата Сообщение от Melvil Посмотреть сообщение
C++
1
2
R = sqrt((x - j)*(x - j) + (y - 0) * (y - 0)); 
   if (R <= 10)
Цитата Сообщение от Temirlan90 Посмотреть сообщение
два целых числа xi и yi - координаты точки
C++
1
2
3
4
5
int R2, x, y;
//...
R2 = (x - j)*(x - j) + (y - 0) * (y - 0); 
   if (R2 <= 100)
//...
будет быстрее.
Да и <cmath> не нужен.
Fulcrum_013
 Аватар для Fulcrum_013
393 / 566 / 60
Регистрация: 14.12.2014
Сообщений: 4,769
Завершенные тесты: 2
05.07.2015, 23:51     Определить количество пораженных мишеней #16
Цитата Сообщение от IrineK Посмотреть сообщение
C++
1
2
3
4
5
int R2, x, y;
//...
R2 = (x - j)*(x - j) + (y - 0) * (y - 0); 
* *if (R2 <= 100)
//...
C++
1
2
3
4
5
6
7
    int R, dx, x, y;
    //....
        dx = x - j; //чтобы лишнее не считать и буковок со скобками меньше писать
        R = dx*dx + y*y;
        if (R <= 100)
            counter += 1;
    //....
Кстати это решение там сейчас и стоит первым.

Добавлено через 5 минут
решение кстати некорректно, но тесты проходит. Нигде нет запрета на то чтобы поразить первой пулей пятую мишень а пятой первую, но это решение такие попадания не зачтет
Melvil
 Аватар для Melvil
47 / 46 / 13
Регистрация: 20.05.2015
Сообщений: 246
06.07.2015, 11:53     Определить количество пораженных мишеней #17
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Кстати это решение там сейчас и стоит первым.
Возможно мы говорим про разные сайты, и да, уже не стоит. Решение и вправду некорректно если стрелять не по порядку. Добавление dx - не нужно, т.к. только увеличивает размер кода, можете проверить сами. Пока что вот так, хотя мне кажется, что можно его уменьшить, используя while вместо for:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
void main()
{
    int x, y, R, counter = 0;
    for (int j = 0; j < 101; j += 25)
    {
        cin >> x >> y;
        R = (x-j)*(x-j) + y*y;
        if (R < 101)
            counter += 1;
    }
    cout << counter;
}
Добавлено через 6 минут
Увы, от цикла ничего не зависит. Однако удалось использовать тернарную операцию:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
void main()
{
    int x, y, R, counter = 0, j=0;
    while (j < 101)
    {
        cin >> x >> y;
        R = (x - j)*(x - j) + y*y;
        counter += 1 ? R < 101 : 0;
        j += 25;
    }
    cout << counter;
}
Fulcrum_013
 Аватар для Fulcrum_013
393 / 566 / 60
Регистрация: 14.12.2014
Сообщений: 4,769
Завершенные тесты: 2
06.07.2015, 12:28     Определить количество пораженных мишеней #18
я про этот сайт.
http://********/index.asp?main=bstatus&id_t=440
Цитата Сообщение от Melvil Посмотреть сообщение
Добавление dx - не нужно, т.к. только увеличивает размер кода
ну если d а не dx то сокращает. читабельность правда страдает

Добавлено через 7 минут
a_c_m_p.ru
Melvil
 Аватар для Melvil
47 / 46 / 13
Регистрация: 20.05.2015
Сообщений: 246
06.07.2015, 12:32     Определить количество пораженных мишеней #19
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
ну если d а не dx то сокращает. читабельность правда страдает
Как вообще возможно сократить данный код ещё на 25 символов ?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.07.2015, 13:11     Определить количество пораженных мишеней
Еще ссылки по теме:

Определить количество слов в заданном тексте и количество символов в каждом слове C++
Определить количество лет, в которые количество осадков превышало среднегодовое C++
Пользователь вводит строку. Определить количество букв (рус eng), количество цифр и количество остальных C++

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

Или воспользуйтесь поиском по форуму:
Fulcrum_013
 Аватар для Fulcrum_013
393 / 566 / 60
Регистрация: 14.12.2014
Сообщений: 4,769
Завершенные тесты: 2
06.07.2015, 13:11     Определить количество пораженных мишеней #20
Цитата Сообщение от Melvil Посмотреть сообщение
Как вообще возможно сократить данный код ещё на 25 символов
ну для начала с вместо counter

Добавлено через 11 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
main()
{   
    int c = 0, R, x, d, y,j=0;
    while(j<101) 
    {
 
        std::cin >> x >> y;     
        d=x-j;
        R =d*d + y*y;
        if(R<101)c++;               
        j += 25;
    }
    std::cout << c;
}
крайний текст. Больше ее не ужать.

Добавлено через 2 минуты
Таки ужал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
main()
{   
    int c = 0, R, x,y,j=0;
    while(j<101) 
    {
 
        std::cin >> x >> y;     
        x-=j;
        R =x*x + y*y;
        if(R<101)c++;               
        j += 25;
    }
    std::cout << c;
}
Добавлено через 2 минуты
Но это был еще не предел.
А вот это уже похоже край:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
main()
{   
    int c = 0, R, x,y,j=0;
    while(j<101) 
    {
 
        std::cin >> x >> y;     
        x-=j;       
        if(x*x + y*y<101)c++;               
        j += 25;
    }
    std::cout << c;
}
Добавлено через 5 минут
край все таки вот: 126 байт
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
main()
{   
    int c = 0, x,y,j=0;
    while(j<101) 
    {
 
        std::cin >> x >> y;     
        x-=j;       
        if(x*x + y*y<101)c++;               
        j += 25;
    }
    std::cout << c;
}
Добавлено через 7 минут
А это почти за краем : 125 байт
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
main()
{   
    int c=0,j=0, x,y;
     while(j<5) 
    {
 
        std::cin >> x >> y;     
        x-=j*25;        
        if(x*x + y*y<101)c++;               
        j++;
    }
    std::cout << c;
}
Добавлено через 8 минут
точно за краем:124 байта
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
main()
{   
    int c=0,j=0, x,y;
    for(;j<5;j++) 
    {
 
        std::cin >> x >> y;     
        x-=j*25;        
        if(x*x + y*y<101)c++;                       
    }
    std::cout << c;
}
Yandex
Объявления
06.07.2015, 13:11     Определить количество пораженных мишеней
Ответ Создать тему
Опции темы

Текущее время: 11:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru