1001
http://acm.hdu.edu.cn/showproblem.php?pid=5018
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stdlib.h> #include <cmath> #include <iomanip> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <cctype> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) #define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z) using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; int dx[8]={0,0,-1,1,1,1,-1,-1}; int dy[8]={1,-1,0,0,-1,1,-1,1}; int f[100]; int a,b,c; bool ok; int main() { int t;rd(t); while(t--) { rd3(a,b,c); if(c==a||c==b) { cout<<"Yes"<<endl; continue; } ok=0; while(1) { int temp=b; b=a+b; a=temp; if(b==c) { ok=1; break; } if(b>c) break; } if(ok) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
http://acm.hdu.edu.cn/showproblem.php?pid=5019
求两个数的第k大公约数,比如 12 18 ,所有公约数为 6 3 2 1 ,那么第二大则为3
首先求出两个数的最大公约数,然后对其分解因子就可以了。注意要用long long类型.
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stdlib.h> #include <cmath> #include <iomanip> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <cctype> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) #define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z) using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; int dx[8]={0,0,-1,1,1,1,-1,-1}; int dy[8]={1,-1,0,0,-1,1,-1,1}; ll factor[10002]; ll len; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } ll x,y,k; int t; bool cmp(ll a,ll b) { return a>b; } int main() { rd(t); while(t--) { scanf("%I64d%I64d%I64d",&x,&y,&k); long long g=gcd(x,y); len=0; for(ll i=1;i<=sqrt(g*1.0);i++) { if(g%i==0) { if(i*i!=g) { factor[len++]=i; factor[len++]=g/i; } else factor[len++]=i; } } if(len<k) cout<<-1<<endl; else { sort(factor,factor+len,cmp); cout<<factor[k-1]<<endl; } } return 0; }
http://acm.hdu.edu.cn/showproblem.php?pid=5020
二维坐标中给出n个点,问3点共线一共有多少组。 0,0 1,0 2,0 3,0 这四个点就有三组, 0,0 1,0 2,0 0,0 1,0 3,0 1.0 2,0 3.0 这三组
固定一个点,加入一个点,方案数为0,此时两点已经确定一条直线,有斜率,再加入一个点,且该点在直线上,那么方案数为1,再加入一个该直线上的点,那么方案数为2,每个方案中都包括一开始固定的那个点,也就是C(3,2)=3 ,接下来是 C(4,2)=6
加入点数 方案数
1 0
2 1
3 3
4 6
5 10 可以看到方案数之间的差是等差数列,遍历每个点,用map<double,int>cnt 保存,通过该点斜率为first,的方案数有多少个,然后再遍历剩下的点,利用上面的规律累加即可,注意直线斜率为0的情况,也就是竖线,两个点的x值相等,单独统计。因为 三个点 1 2 3 和 2 3 1为一种方案,所以两重循环遍历的时候 for (int i=1 ....) for(int j= i+1 ,.....)
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stdlib.h> #include <cmath> #include <iomanip> #include <vector> #include <set> #include <map> #include <stack> #include <queue> #include <cctype> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) #define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z) using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; int dx[8]={0,0,-1,1,1,1,-1,-1}; int dy[8]={1,-1,0,0,-1,1,-1,1}; int t; int n; map<double,int>cnt;//斜率和点的个数 struct P { int x; int y; }p[1002]; ll ans; int main() { rd(t); while(t--) { cnt.clear(); ans=0; int tot=0; rd(n); for(int i=1;i<=n;i++) rd2(p[i].x,p[i].y); for(int i=1;i<=n;i++)//与i点共线的有哪些点,tot是判断竖线有多少个点 { tot=0;//注意这里每次都得初始化 cnt.clear(); for(int j=i+1;j<=n;j++) { if(p[i].x==p[j].x) { ans+=tot; tot++; continue; } double pl=(p[j].y-p[i].y)*1.0/(p[j].x-p[i].x); ans+=cnt[pl]; cnt[pl]++; } } cout<<ans<<endl; } return 0; }
原文:http://blog.csdn.net/sr_19930829/article/details/43525337