F題 沒做,大概是一道二維掃描線的題,代碼很長並不想打了
G題 郭大俠與陰陽家 好像是排個序強行掃一道就判斷出來了,我記得也不是太清楚.
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define eps 1e-9
using namespace std;
struct node{
int x,y;
}e[2005];
struct juxing{
double x,y,wx,wy,dis;
}a[4000005];
int n,ans,f[2005];
bool cmp(node a,node b)
{
if (a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
bool cmp1(juxing a,juxing b)
{
if (a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&e[i].x,&e[i].y);
}
sort(e+1,e+1+n,cmp);
for (int i=1;i<n;i++)
{
if (e[i].x==e[i+1].x&&e[i].y==e[i+1].y) f[i]=1;
}
int cnt=0;
for (int i=1;i<n;i++)
for (int j=i+1;j<=n&&!f[i];j++)
{
if (!f[j])
{
a[++cnt].x=(e[i].x+e[j].x)/2.0;
a[cnt].y=(e[i].y+e[j].y)/2.0;
if (e[j].x-e[i].x==0)
{
a[cnt].wy=772237;
a[cnt].wx=e[i].x;
a[cnt].dis=2223333;
continue;
}
double k=(e[j].y-e[i].y)*1.0/(e[j].x-e[i].x);
double b=e[i].y-k*e[i].x;
a[cnt].wy=b;
if (k==0) a[cnt].wx=-20000000;
else a[cnt].wx=-b/k;
a[cnt].dis=k+b;
}
}
sort(a+1,a+1+cnt,cmp1);
for (int i=1;i<cnt;i++)
{
for (int j=i+1;j<=cnt&&abs(a[i].x-a[j].x)<eps&&abs(a[i].y-a[j].y)<eps;j++)
{
if (!(abs(a[i].wy-a[j].wy)<eps&&abs(a[i].dis-a[j].dis)<eps))
ans++;
}
}
printf("%d",ans);
}
H 郭大俠與英雄學院
先排個序,然後填,用一個並查集維護一下相同的值就可以啦.
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int ans[1000005],fa[1000005],xm[1000005],ym[1000005],n,m,hx[1000005],hy[1000005];
int bb;
struct node{
int v,x,y;
}a[1000005];
int find(int x)
{
return x!=fa[x]?fa[x]=find(fa[x]):x;
}
bool cmp(node a,node b)
{
return a.v<b.v;
}
void f(int a,int b)
{
int x=find(a);
int y=find(b);
if (x!=y)
fa[x]=y;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n*m;i++)
{
scanf("%d",&a[i].v);
a[i].x=i/m+1;
a[i].y=i%m;
if (a[i].y==0)
{
a[i].y=m;
a[i].x--;
}
}
sort(a+1,a+1+n*m,cmp);
for (int i=1;i<=n*m;i++)
{
fa[i]=i;
}
int xiangtong=1;
for (int i=1;i<=n*m;i++)
{
if (i!=n*m&&a[i].v==a[i+1].v)
{
continue;
}
for (int j=xiangtong;j<=i;j++)
{
hx[a[j].x]=hy[a[j].y]=(a[j].x-1)*m+a[j].y;
}
for(int j=xiangtong;j<=i;j++)
{
f(hx[a[j].x],(a[j].x-1)*m+a[j].y);
f(hy[a[j].y],(a[j].x-1)*m+a[j].y);
}
for (int j=xiangtong;j<=i;j++)
{
int x=a[j].x;int y=a[j].y;
int z=find((x-1)*m+y);
ans[z]=max(ans[z],max(xm[x],ym[y])+1);
}
for (int j=xiangtong;j<=i;j++)
{
int x=a[j].x;int y=a[j].y;
xm[x]=max(xm[x],ans[find((x-1)*m+y)]);
ym[y]=max(ym[y],ans[find((x-1)*m+y)]);
}
xiangtong=i+1;
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
printf("%d ",ans[find((i-1)*m+j)]);
}
printf("\n");
}
return 0;
}
I 郭大俠與線上遊戲
學會set這個stl庫的東西,因爲中位數只會在原中位數的左右一位改動,所以插入後判斷即可.
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <set>
#include <queue>
using namespace std;
int n,t,x,aaa;
set<int> lset,rset;
queue<int>q;
int main()
{
scanf("%d",&n);
while (n--)
{
scanf("%d",&t);
if (t==1)
{
scanf("%d",&x);
q.push(x);
if (rset.empty()){rset.insert(x);}
else
{
if (lset.empty())
{
if (x>*rset.begin())
{
lset.insert(*rset.begin());
rset.erase(rset.begin());
rset.insert(x);
}
else
{
lset.insert(x);
}
}
else if (x>=*rset.begin())
{
if (lset.size()==rset.size())
{
rset.insert(x);
}
else
{
lset.insert(*rset.begin());
rset.erase(rset.begin());
rset.insert(x);
}
}
else
{
if (lset.size()==rset.size())
{
lset.insert(x);
rset.insert(*lset.rbegin());
lset.erase(--lset.end());
}
else
{
lset.insert(x);
}
}
}
}
else if (t==2)
{
x=q.front();
q.pop();
if (lset.empty())
{
rset.erase(*rset.begin());
}
else
{
if (x>=*rset.begin())
if (lset.size()==rset.size())
{
rset.erase(rset.lower_bound(x));
rset.insert(*lset.rbegin());
lset.erase(--lset.end());
}
else
{
rset.erase(rset.lower_bound(x));
}
else if (lset.size()==rset.size())
{
lset.erase(lset.lower_bound(x));
}
else
{
lset.erase(lset.lower_bound(x));
lset.insert(*rset.begin());
rset.erase(rset.begin());
}
}
}
else
{
printf("%d\n",*rset.begin());
}
}
}