Codeforcs1163B 数据结构 模拟 C计算几何

https://codeforces.com/contest/1163/problem/B2

#include <bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define pb push_back
#define mp make_pair
#define IO ios::sync_with_stdio(false)
#define fi first
#define se second
using namespace std;
const int maxn=2e5+5;
typedef long long ll;
typedef pair<int,int> pii;

string s,t;
int n;
int color,f[maxn],cnt[maxn],mx=0,ans;
//376EF
int main(){
	
	cin>>n;
	rep(i,1,n){
		bool ok=false;
		cin>>color;
		cnt[f[color]]--;	//开始f[color]=0次 cnt[0]=-1 
		f[color]++;
		cnt[f[color]]++;	//cnt[2]=1 1种颜色出现2次
		mx=max(mx,f[color]);	//某种颜色最大出现次数
		if(cnt[i]==1)	//1种颜色出现i次
			ok=true;
		else if(cnt[1]==i)	//每种颜色各出现1次 
			ok=true; 
		else if(cnt[1]==1 && cnt[mx]*mx==i-1)	//1 1 1 2 一种颜色出现1次 另一种颜色出现i-1次 2 1 1 1一样 3 3 3 1
			ok=true;
		else if(cnt[mx]==1 && cnt[mx-1]*(mx-1)==(i-mx)) 	//2 2 3 3 3     1种颜色出现mx次 另一种颜色出现mx-1次 比他多一次 
			ok=true;
		if(ok)
			ans=i;
		
	}
	cout<<ans<<endl;
	return 0;
}


map set multiset都可
C

#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
struct Point
{
	ll x,y;
	Point(ll xx=0,ll yy=0){x=xx,y=yy;}
	Point operator+(Point p){return Point(x+p.x,y+p.y);}
	Point operator-(Point p){return Point(x-p.x,y-p.y);}
	bool operator==(Point p){return x==p.x&&y==p.y;}
	ll det(Point p){return x*p.y-y*p.x;}
	Point unit()
	{
		if(x<0||(x==0&&y<0))x=-x,y=-y;
		ll d=__gcd(x,y);
		if(d<0)d=-d;
		return Point(x/d,y/d);
	}
}a[1005];
struct Line
{
	Point st,v;
	bool operator==(Line b)
	{
		return v==b.v&&(st==b.st||(st-b.st).unit()==v);
	}
}p[1000005];
ll n,top;
bool cmp(Line a,Line b)
{
	return a.v.x<b.v.x||(a.v.x==b.v.x&&a.v.y<b.v.y)||(a.v==b.v&&a.st.det(a.v)<b.st.det(b.v));
}
int main()
{
	scanf("%I64d",&n);
	for(int i=1;i<=n;i++)scanf("%I64d%I64d",&a[i].x,&a[i].y);
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	{
		p[++top].v=a[i]-a[j];
		p[top].st=a[j];
		p[top].v=p[top].v.unit();
	}
	sort(p+1,p+top+1,cmp);
	for(int i=top;i>=2;i--)
	  if(p[i]==p[i-1])
		p[i].v=Point(2147483647,2147483647);
	sort(p+1,p+top+1,cmp);
	while(p[top].v.x==2147483647)top--;
	ll ans=0,num=0;
	for(int i=1;i<=top;i++)
	{
		if(p[i]==p[i-1])continue;
		if(p[i].v==p[i-1].v)num++;
		else
		{
			ans+=num*(num+1)/2;
			num=0;
		}
	}
	ans+=num*(num+1)/2;
	printf("%I64d\n",(top*top-top)/2-ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值