题解:
拿到这道题,题目中提出奇数的个数少于等于一个(没有奇数就无解),我们可以很容易的利用好一个性质:一串偶数加上一个奇数必定是一个奇数;
我们二分一个奇数的位置,\(O(N)\)求前缀和,如果这个位置之前的和为奇数,那么我们将右边界左移,否则左边界右移;
\(code\):
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<cmath>
#include<stdlib.h>
#include<ctime>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#define fuck puts("There's no weakness.")
#define mod 998244353
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
const int maxn=1000001<<1;
struct node{
int x,y,w;
inline node(int a=0,int b=0,int c=0)
{x=a,y=b;w=c;}
}a[maxn];
int n,t,l=1,r;
bool ok(int x)
{
int tot=0;
for(int i=1;i<=n;i++)
if(a[i].x<=x) tot+=((min(a[i].y,x)-a[i].x)/a[i].w)+1;
return tot&1;
}
int cal(int x)
{
int tot=0;
for(int i=1;i<=n;i++)
tot+=(a[i].x<=x&&a[i].y>=x&&(x-a[i].x)%a[i].w==0);
return tot;
}
int main()
{
//freopen("defend.in","r",stdin);
//freopen("defend.out","w",stdout);
read(t);
while(t--)
{
read(n);
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
int x,y,z;
read(x),read(y),read(z);
a[i]=node(x,y,z);
r=max(r,y);
}
bool flag=0;int ans=0;l=1;
while(l<=r)
{
int mid=l+r>>1;
if(ok(mid)){ans=mid,r=mid-1,flag=1;}
else l=mid+1;
}
if(flag) printf("%d %d\n",ans,cal(ans));
else fuck;
}
return 0;
}
题解:
显然两点之间的距离\(dis(t)\)是一个关于时间t二次函数开方,对于所有的点对所组成的二次函数,我们每个图像都有一个极值,这些极值所组成的函数依旧是一个单峰函数,否则这道题就多解了,三分一个时间,\(O(N^2)\)验证即可;
\(code:\)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<cmath>
#include<stdlib.h>
#include<ctime>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#define fuck puts("There's no weakness.")
#define mod 998244353
#define eps 1e-7
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
const int maxn=302;
struct node{
ld x,y,a,b;
inline node(ld t1=0,ld t2=0,ld t3=0,ld t4=0)
{x=t1,y=t2,a=t3,b=t4;}
}a[maxn];
int n;
bool same(ld a,ld b){return fabs(a-b)<=eps;}
ld pow_(ld a)
{return a*a;}
ld cal(int i,int j,ld t)
{
ld a1=a[i].a,b1=a[i].b,x1=a[i].x,y1=a[i].y;
ld a2=a[j].a,b2=a[j].b,x2=a[j].x,y2=a[j].y;
ld nowx1=a1*t+x1,nowy1=b1*t+y1;
ld nowx2=a2*t+x2,nowy2=b2*t+y2;
return pow_(nowx1-nowx2)+pow_(nowy1-nowy2);
}
ld fx(ld t)
{
ld ans=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
ans=max(ans,cal(i,j,t));
return sqrt(ans);
}
int main()
{
//freopen("dis.in","r",stdin);
//freopen("dis.out","w",stdout);
read(n);
for(int i=1;i<=n;i++)
{
ld x,y,aa,bb;
read(x),read(y),read(aa),read(bb);
a[i]=node(x,y,aa,bb);
}
ld l=0.0,r=1e9*1.0,lmid,rmid;
while(!same(l,r))
{
lmid=l+(r-l)/3;
rmid=r-(r-l)/3;
if(fx(lmid)<=fx(rmid)) r=rmid;
else l=lmid;
}
printf("%.2lf %.2lf",r,fx(r));
return 0;
}
题解:
之前一直做不来这种题,这次下决心将它弄懂之后有一定的感悟\(,,,\)
对于这类分形递归的题,我们可以根据点数较少的图,找当前图点与上一张图的点之间的关系,找出的关系只要是一定程度上合理的,那么它必定对我们的每次递归都会成立;
设定一下递归边界即可;
\(code:\)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<ctype.h>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<cmath>
#include<stdlib.h>
#include<ctime>
#define lowbit(x) (x&-x)
#define ll long long
#define ld double
#define fuck puts("There's no weakness.")
#define mod 998244353
using namespace std;
char buf[1<<20],*p1,*p2;
inline char gc()
{
// return getchar();
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin))==p1?0:*p1++;
}
template<typename T>
inline void read(T &x)
{
char tt;
bool flag=0;
while(!isdigit(tt=gc())&&tt!='-');
tt=='-'?(flag=1,x=0):(x=tt-'0');
while(isdigit(tt=gc())) x=x*10+tt-'0';
if(flag) x=-x;
}
ll a[32],cnt[32];
ld pow_(ld a){return a*a;}
void dfs(ll n,ll id,ld &x,ld &y)
{
if(n==1)
{
if(id==1) x=1,y=1;
if(id==2) x=1,y=3;
if(id==3) x=3,y=3;
if(id==4) x=3,y=1;
return;
}
ld tx,ty;
int flag=(id-1)/cnt[n]+1;
if(flag==1)
{
dfs(n-1,id,tx,ty);
x=ty,y=tx;
}
if(flag==2)
{
dfs(n-1,id-cnt[n],tx,ty);
x=tx,y=a[n-1]+ty;
}
if(flag==3)
{
dfs(n-1,id-(cnt[n]<<1),tx,ty);
x=a[n-1]+tx,y=a[n-1]+ty;
}
if(flag==4)
{
dfs(n-1,id-cnt[n]*3,tx,ty);
x=a[n]-ty,y=a[n-1]-tx;
}
}
ld cal(ld x1,ld y1,ld x2,ld y2)
{
return sqrt(pow_(x1-x2)+pow_(y1-y2))*5;
}
ll n,aa,bb,t;
int main()
{
read(t);a[1]=4,cnt[1]=1;
for(int i=2;i<=31;i++)
a[i]=a[i-1]<<1,cnt[i]=cnt[i-1]<<2;
while(t--)
{
ld x1,x2,y1,y2;
read(n),read(aa),read(bb);
dfs(n,aa,x1,y1);
dfs(n,bb,x2,y2);
printf("%.0lf\n",cal(x1,y1,x2,y2));
}
}