题目
输入n,问从坐标(0,0)点能看到多少点,点的坐标范围是0<=(x,y)<=n
只有一个点没有被另一个点挡住才能看到。
如上图,n=5的时候,能看到21个点
Input
第一行输入t,表示样例个数。1<=t<=1000 接下来t行,每行输入一个正整数n 。 1<=n<=1000
Output
输出n行三列。
第一列从1到n表示第i个样例,第二列输出n,第三列输出能看到的点的个数
题解
过原点能做几条范围在n内的过整数点的线,定点做线的区分是斜率,所以问题再次转换为,求整点斜率的问题。
数据范围不大,n<=1000,说明O(n^2)复杂度的方法或许可行,但查询t<=1000,如果要使用,O(n^2)的需要预先处理,这题求出n的数的同时也会求出1~n-1的数所以很容易预先打表。
可以使用stl的map容器进行对斜率的唯一标识,来暴力计算斜率个数。
也可以使用gcd来判断gcd是否是1来唯一标识,来暴力计算斜率个数。
但map判断会超时
AC代码
#include<iostream> using namespace std; int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } const int max_n = 1000; int b[max_n+5]; int main() { int T, n; scanf("%d", &T); int ans = -1;//因为下面的判断当i==j时会判断两次,所以减1 for (int i = 1; i <= max_n; i++) { for (int j = 0; j <= i; j++) { if (gcd(i, j) == 1)ans++; if (gcd(j, i) == 1)ans++; } b[i] = ans; } for (int t = 1; t <= T; t++) { scanf("%d", &n); printf("%d %d %d ",t,n,b[n]); } return 0; }