题目链接:https://codeforces.com/gym/102174/problem/H
小白非常不擅长数论,在强老师的数论课上,小白听着听着又睡着了(毕竟梦里什么都有)。小白梦见自己成为了数论大师,只用了三分钟就熟练地写出了一道拉格朗日反演套多项式逆元和快速数论变换的好题。但是当他醒来一看,他还是对数论的题目一窍不通。现在就有一道简单题摆在小白的面前,聪明的你能帮帮他吗?
定义经过函数的一次映射就能回到自身的点为函数的不动点(Fix Point)。换句话说,给定函数 f(x),它的不动点就是所有使得 f(x)=x 成立的 x 的集合。如函数 f(x)=x 有无穷多个不动点,而函数 f(x)=2x−1 则只有 x=1 这一个不动点。请你找出函数 f(x)= 的所有不动点。
Input
第一行输入一个正整数 T (1≤T≤100),表示数据组数。
接下来 T 组数据,每组数据输入两个整数 a 和 b (−103≤a,b≤103),描述本组输入的函数 f(x)= ,保证该函数至少存在一个不动点,且所有的不动点均为整数。
Output
对于每组数据,第一行请输出一个正整数 k,表示函数f(x)= 的不动点个数。第二行请从小到大依次输出 k 个整数 x1,x2,⋯,xk (x1<x2<⋯<xk) 由空格间隔开,描述函数 f(x) 的不动点集合,注意换行。
Example
inputCopy
2
1 0
0 1
outputCopy
2
0 1
1
1
思路:关键就是求解 的解,即化为一元二次方程的解,但是特别要注意一点增根的问题,就是根号必须保证值要非负,所以x + b必须大于零。因为这个卡了好久,开方一定要注意。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <string>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int N = 1e5 + 7, M = 1e5 + 7, mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double PI = acos(-1.0);
int main()
{
int t; scanf("%d", &t);
while (t -- )
{
vector<int> ans, temp;
int a, b; scanf("%d%d", &a, &b);
int x1 = 2 * b + a - sqrt(4 * b * a + a * a);
int x2 = 2 * b + a + sqrt(4 * b * a + a * a);
if (x1 == x2) temp.push_back(x1 / 2);
else
{
if (x1 % 2 == 0) temp.push_back(x1 / 2);
if (x2 % 2 == 0) temp.push_back(x2 / 2);
}
for (auto item : temp)
if (item >= b) ans.push_back(item);
printf("%d\n", ans.size());
for (auto item : ans)
printf("%d ", item);
printf("\n");
}
return 0;
}