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;
}
1002
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;
}
1003
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;
}