- 题意就是给你n个点,要求原点在圆的边界上,问在圆上的点的最多的圆,输出边界上有题中所给点的最大个数。
我一开始读错题意了。以为是以原点为圆心。。然后直接遍历每个点和其他点的距离就是半径个数取最大,样例也过了。。
但是后来发现原点是在边界上的。。这道题其实就可以利用三点构成一个圆,我们将每两个点组合然后再包括原点,求出圆心,
求出所有的圆心用map存入,那么他的最大的size()+1就是他的圆上最大的点数,因为一个圆心他有1次的时候,
这时候在上面是有2个点的,因为原点和那两个点组成的圆心,但是原点不算,因此此时有两个点,当圆心出现了两次,
那么说明比之前又多了一个另外的点,这时候就会有两次圆心,
前提是遍历点的时候是i(1,n),j(i+1,n),这样就避免了重复的情况。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <map>
#include <string>
#include <stack>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include<limits.h>
#define S(X) scanf("%d",&(X))
#define SS(X, Y) scanf("%d%d",&(X),&(Y))
#define SSS(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z))
#define SL(X) scanf("%lld",&(X))
#define SLL(X, Y) scanf("%lld%lld",&(X),&(Y))
using namespace std;
typedef double db;
typedef long long ll;
const int mod = 998244353;
const double eps = 1e-6;
const int maxn = 4e3 + 7;
struct Point
{ //点
double x,y;
Point(){}
Point(double _x,double _y)
{
x = _x; y = _y;
}
Point operator +(const Point &b)const
{
return Point(x + b.x, y + b.y);
}
Point operator -(const Point &b)const
{
return Point(x - b.x, y - b.y);
}
bool friend operator<(const Point& p1,const Point& p2){
if(fabs(p1.x-p2.x)>eps)return p1.x<p2.x;return p1.y<p2.y;
}
double operator *(const Point &b)const
{ //点积
return x*b.x + y*b.y;
}
double friend operator^(const Point& p1,const Point& p2){
return p1.x*p2.y-p2.x*p1.y;
}
}p[maxn];
map<Point,int>mp;
Point xin(Point a, Point b, Point c)
{
double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1 * a1 + b1 * b1) / 2.0;
double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2 * a2 + b2 * b2) / 2.0;
double d = a1 * b2 - a2 * b1;
return Point(a.x + (c1 * b2 - c2 * b1) / d, a.y + (a1 * c2 - a2 * c1) / d);
}
int main(){
int n;
S(n);
for(int i = 0;i < n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
if(n <= 2) {
printf("%d\n",n);
return 0;
}
int ans=0;
for(int i = 0;i < n;i++){
mp.clear();
for(int j = i + 1;j < n;j++){
if(abs(p[i] ^ p[j]) >= eps) {
Point xinn= xin(Point(0,0),p[i],p[j]);
mp[xinn]++;
ans = max(ans,mp[xinn]);
}
}
}
printf("%d\n", ans + 1);
return 0;
}
- 很容易发现就是找叶子结点就可以了,然后将他们输出即可,数据有点假感觉。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <map>
#include <string>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#define S(X) scanf("%d",&(X))
#define SS(X, Y) scanf("%d%d",&(X),&(Y))
#define SSS(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z))
#define SL(X) scanf("%lld",&(X))
#define SLL(X, Y) scanf("%lld%lld",&(X),&(Y))
using namespace std;
typedef double db;
typedef long long ll;
const int mod = 998244353;
const int maxn=5e5+100;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen(".vscode/in.txt","r",stdin);
#endif
vector<int>v;
int n;
S(n);
int a[maxn];
int x,y;
for(int i=0;i<n-1;i++)
{
SS(x,y);
a[x]++;a[y]++;
}
for(int i=1;i<=n;i++)
{
if(a[i]==1)
v.push_back(i);
}
printf("%d\n",(v.size()+1)/2);
for(int i=0;i<(v.size()+1)/2;i++)
{
printf("%d %d\n",v[i],v[i+v.size()/2]);
}
return 0;
}
- 完全签到题。给你时间求出秒数,一小时3600秒,一分钟60秒,做差即可。
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<string.h>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<map>
#include<stack>
#include<list>
#define pii pair<int, int>
#define pll pair<LL, LL>
#define pil pair<int, LL>
#define pli pair<LL, int>
#define mp make_pair
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const LL LLINF = 1e18;
const int INF = 1e9;
const int MOD = 20101009;
const int HMOD = 999959;
const int VMOD = 5000000;
const int MAXN = 3e5+10;
const int MAXM = 5e5+10;
const int INV = 10050505;
const LL LLINV = 1e18;
const double eps = 1e-3;
int dirx[5] = {0, -1, 1, 0, 0}, diry[5] = {0, 0, 0, -1, 1};
int h1, m1, s1, h2, m2, s2;
int main()
{
IOS;
scanf("%d:%d:%d", &h1, &m1, &s1);
scanf("%d:%d:%d", &h2, &m2, &s2);
int l = h1*3600+m1*60+s1, r = h2*3600+m2*60+s2;
printf("%d\n", abs(r-l));
return 0;
}
- 这题没用单调队列维护,用dp直接过了,题目要求你算出所有k*k的子矩阵里面最大的元素之和,那么你把每个元素当前的值变成左边和上面的元素的最大值,那么矩阵lcm[k][k]这个位置就是第一个子矩阵的最大值,同理之后每一个元素都是一个子矩阵的最大值,我们只要将[k][k]~[n][m]这里面的元素累加即可。蛮假的。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <map>
#include <string>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#define S(X) scanf("%d",&(X))
#define SS(X, Y) scanf("%d%d",&(X),&(Y))
#define SSS(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z))
#define SL(X) scanf("%lld",&(X))
#define SLL(X, Y) scanf("%lld%lld",&(X),&(Y))
using namespace std;
typedef double db;
typedef long long ll;
const int mod = 998244353;
const int maxn=2e5+100;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen(".vscode/in.txt","r",stdin);
#endif
int lcm[5005][5005]={0};
int n,m,k;
SSS(n,m,k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
lcm[i][j]=(i*j)/(__gcd(i,j));
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=m;j++)
// {
// cout<<lcm[i][j]<<" ";
// }
// cout<<endl;
// }
if(k!=1){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
lcm[i][j]=max(lcm[i][j],max(lcm[i-1][j],lcm[i][j-1]));
}
ll ans=0;
for(int i=k;i<=n;i++)
for(int j=k;j<=m;j++)
ans+=lcm[i][j];
printf("%lld\n",ans);
return 0;
}