Проверьте, является ли число суммой двух квадратов в C

#c #math

#c #математика

Вопрос:

Мне нужна ваша помощь в решении этой проблемы, я пытался решить ее весь день, но не могу найти решение. Я только начал изучать C, поэтому прошу прощения, если это глупый вопрос, однако мне разрешено использовать только:

  • if
  • for
  • do-while
  • while

инструкции для решения проблемы.

Мне нужно проверить, может ли данное число быть записано как сумма двух квадратов, мне не нужно знать, какие это два квадрата, и мне не нужно анализировать случаи, когда число равно 0 или 1. То, что мне удалось построить до сих пор, это:

 unsigned int x;
unsigned int q = 1;
printf("Enter a number : n");
scanf("%u", amp;x);
unsigned int j = sqrt(x - (q*q));
if (x != 1 amp;amp; x != 0)
    for (q; (q*q) <= (x/2); q  )
        if ((x - (q*q)) == (j*j))
printf("Given number is sum of two squares");
 

Это иногда работает, а иногда нет, например, оно работает для 65 (8^2 1^2) и 90 (9^2 3^2) , но не будет работать, когда я добавлю 181 (10^2 9^2) и так далее..
У вас есть какие-либо идеи, как я могу это исправить?

Комментарии:

1. Итак, никаких возвращений или выражений, подобных a = b; ? Извините, это невозможно. Ваш код уже нарушает ограничения.

2. Извините за мою ошибку, я могу использовать выражения типа a = b,

3. Да, это ясно, поскольку while etc. не работает без. Но можете ли вы также использовать выражения-операторы ?

4. Да, я могу их использовать!

5. Обратите внимание, что число N является суммой 2 квадратов тогда и только тогда, когда при разложении N на простые множители каждое простое число вида (4k 3) встречается четное число раз.

Ответ №1:

Хорошо, итак, вот псевдокод для возможного решения:

 Input x;

int a;
int b;

for(a=0; a <= x; a  ){

   for(b=a; b <= x; b  ){

      if((a*a   b*b) == x){
         Output is_solution;
      }

   }

}
 

Во вложенном цикле b присваивается значение a , чтобы избежать проверки одной и той же суммы квадратов более одного раза.

Преобразование этого в C должно выглядеть следующим образом:

 unsigned int x;
unsigned int a;
unsigned int b;

printf("Enter a number : n");
scanf("%u", amp;x);

for(a=0; a<=x; a  ){
   for(b=a; b<=x; b  ){
      if((a*a   b*b) == x){
         printf("Given number is sum of two squares");
      }
   }
}
 

Я немного заржавел в C, надеюсь, в нем нет неприятных ошибок.

Комментарии:

1. Спасибо за ваш ответ, я попытался скомпилировать его, но похоже, что он печатает «заданное число ..» для каждого введенного мной числа

2. sqrt(a) вычисляет квадратный корень из a , а не из квадрата a . И, очевидно, каждое натуральное число является суммой двух квадратных корней.

3. @chtz, вы правы, моя ошибка, спасибо. Цюрупета, я обновил свой ответ на случай, если вы захотите попробовать еще раз.

4. извините, @DavidNeto, у меня есть время, чтобы сделать комментарий, но не сегодня, чтобы написать полное решение проблемы. Но идея понятна и хороша для использования в качестве упражнения.

Ответ №2:

Вам нужно поместить вычисление j внутри for цикла. В настоящее время вы вычисляете только j для q=1 .

Я рекомендую помещать блоки циклов и if в фигурные скобки. Т.е.,

  if(condition)
 {
     // statements
 }
 

Комментарии:

1. Но я не понимаю, если я вычисляю только J для q = 1, как программа может найти 90 (9^2 3^2) ?

2. Поскольку x=90 вы вычисляете sqrt(90-1)=9.48.... , что при сохранении как int округляется до 9.

3. Ах, я понимаю, так что это должно быть что-то вроде этого? for (q; (q q) <= (x /2); q ){j = sqrt(x — (q q)) } if ((x — (q q)) == (j j)) { printf(«Данное число является суммой двух квадратов»);}

4. @Tsurupeta закрыть, но if , конечно, оно должно быть и в блоке for цикла.

5. Похоже, теперь это работает, наконец, большое вам спасибо! Но последний вопрос, иногда J имеет правильное значение, но иногда это дает мне совершенно неожиданный результат, например, если я ввожу 200 Дж, это 1410, если я ввожу 1000 Дж, становится 3026 .. что-то не так с моим кодом?