2018牛客网多校训练3

https://www.nowcoder.com/acm/contest/141#question

过了4题,rank109

H:水题,枚举gcd(i,j)即可, solved by wyq and lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 10000000
int pri[maxn+5];
int a[maxn+5];
int n;
void getPrime()
{
	int i,j;
	for (i=2;i<=maxn;i++)
	{
		if (pri[i]==0) pri[++pri[0]]=i;
		for (j=1;j<=pri[0] && pri[j]<=maxn/i;j++)
		{
			pri[pri[j]*i]=1;
			if (i%pri[j]==0) break;
		}
	}
}

int main()
{
	getPrime();
	scanf("%d",&n);
	for (int i=1;i<=pri[0];i++)
	{
		a[pri[i]]=1;
	}
	for (int i=1;i<=maxn;i++)
	{
		a[i]=a[i-1]+a[i];
	}
	ll ans=0;
	for (int i=1;i<=n;i++)
	{
		ans+=(ll)a[n/i]*(ll)(a[n/i]-1);
	}
	printf("%lld\n",ans);
	return 0;
}

A:四维dp,一开始数据错了,后来rejudge了发现自己还是错了,发现自己还是写错了,GG  solved by lyy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(x,n) for (int x=n;x>=0;x--)
#define per(x,n) for (int x=0;x<=n;x++)
int dp[40][40][40][40];
int dp2[40][40][40][40];
char pre[37][37][37][37][37];
struct st
{
	int id;
	int p,a,c,m,g;
}a[40];
int n;
int P,A,C,M;
vector<int> v;

void dfs(int step,int x1,int x2,int x3,int x4)
{
	if (x1+x2+x3+x4==0) return;
	else
	{
		while (step>=2 && pre[step][x1][x2][x3][x4]==0) step--;
		int i=pre[step][x1][x2][x3][x4];
		v.push_back(pre[step][x1][x2][x3][x4]);
		dfs(step-1,x1-a[i].p,x2-a[i].a,x3-a[i].c,x4-a[i].m);
	}
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d%d%d%d",&a[i].p,&a[i].a,&a[i].c,&a[i].m,&a[i].g);
		a[i].id=1;
		if (a[i].p+a[i].a+a[i].c+a[i].m==0)
		{
			v.push_back(i);
			a[i].id=-1;
		}
	}
	scanf("%d%d%d%d",&P,&A,&C,&M);
	memset(dp,-1,sizeof(dp));
	dp[0][0][0][0]=0;
	for (int i=1;i<=n;i++)
	{
		if (a[i].id==-1) continue;
		rep(x1,P)
		{
			rep(x2,A)
			{
				rep(x3,C)
				{
					rep(x4,M)
					{
						dp2[x1][x2][x3][x4]=dp[x1][x2][x3][x4];
					}
				}
			}
		}
		rep(x1,P-a[i].p)
		{
			rep(x2,A-a[i].a)
			{
				rep(x3,C-a[i].c)
				{
					rep(x4,M-a[i].m)
					{
						if (dp[x1][x2][x3][x4]>=0)
						{
							if (dp[x1+a[i].p][x2+a[i].a][x3+a[i].c][x4+a[i].m]<dp[x1][x2][x3][x4]+a[i].g)
							{
								dp2[x1+a[i].p][x2+a[i].a][x3+a[i].c][x4+a[i].m]=dp[x1][x2][x3][x4]+a[i].g;
								pre[i][x1+a[i].p][x2+a[i].a][x3+a[i].c][x4+a[i].m]=i;
							}
						}
					}
				}
			}
		}
		rep(x1,P)
		{
			rep(x2,A)
			{
				rep(x3,C)
				{
					rep(x4,M)
					{
						dp[x1][x2][x3][x4]=dp2[x1][x2][x3][x4];
					}
				}
			}
		}
	}
	int ans=-1;
	int p,a,c,m;
	per(x1,P)
	{
		per(x2,A)
		{
			per(x3,C)
			{
				per(x4,M)
				{
					if (dp[x1][x2][x3][x4]>ans)
					{
						ans=dp[x1][x2][x3][x4];
						p=x1;
						a=x2;
						c=x3;
						m=x4;
					}
				}
			}
		}
	}
	dfs(n,p,a,c,m);
	printf("%d\n",v.size());
	for (int i=0;i<v.size();i++)
	{
		printf("%d",v[i]-1);
		if (i!=(int)v.size()-1) printf(" ");
	}
	printf("\n");
	return 0;
}

E:处理一下KMP中的next数组  solved by sdn

#include <bits/stdc++.h>
using namespace std;
#define ll long long
 
const int maxx = 1e6+7;
char s[maxx];
int kmpnext[maxx];
void kmp_pre(char x[],int m)
{
    int i,j;
    j = kmpnext[0] = -1;
    i = 0;
    while(i < m)
    {
        while(-1 != j && x[i] != x[j]) j = kmpnext[j];
        kmpnext[++i] = ++j;
    }
}
int main()
{
    scanf("%s",s);
    int n = strlen(s);
    kmp_pre(s,n);
    int len;
    if(n % (n-kmpnext[n]) == 0) len = n-kmpnext[n];
    else len = 0;
    if(len != 0)
    {
        printf("%d\n",len);
        for(int i = 0; i < len; i++)
        {
            printf("%d",n/len);
            for(int j = 0; j < n/len; j++)
            {
                printf(" %d",i+j*len);
            }
            printf("\n");
        }
    }
    else{
        printf("%d\n",n);
        for(int i = 0; i < n; i++)
        {
            printf("1 %d\n",i);
        }
    }
    return 0;
}

J:队友直接上网找了一个模板,发现WA了,试了几组之后发现模板只能处理逆时针给出的多边形,顺时针会返回0,所以把多边形的点倒过来再算一次,取最大值  solved by wyq

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define eps 1e-8
struct Point
{
	double x;
	double y;
	Point(double x=0,double y=0):x(x),y(y) {}
}point[205],cpoint[205];
double areaofp(int vcount)
{
	int i;
	double s;
	if(vcount<3)return 0;
	s=point[0].y*(point[vcount-1].x-point[1].x);
	for(i=1;i<vcount;i++)
	{
		s+=point[i].y*(point[i-1].x-point[(i+1)%vcount].x);
	}
	return s/2;
}
/*	
????hdu5130
????圆与多边形面积交模板
 */
typedef Point Vector;
struct Circle{
    Point c;
    double r;
};
int dcmp(double x) {
    if(x < -eps) return -1;
    if(x > eps) return 1;
    return 0;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) { 
return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double TriAngleCircleInsection(Circle C, Point A, Point B)
{
    Vector OA = A-C.c, OB = B-C.c;
    Vector BA = A-B, BC = C.c-B;
    Vector AB = B-A, AC = C.c-A;
    double DOA = Length(OA), DOB = Length(OB),DAB = Length(AB), r = C.r;
    if(dcmp(Cross(OA,OB)) == 0) return 0;
    if(dcmp(DOA-C.r) < 0 && dcmp(DOB-C.r) < 0) return Cross(OA,OB)*0.5;
    else if(DOB < r && DOA >= r) {
        double x = (Dot(BA,BC) + sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB;
        double TS = Cross(OA,OB)*0.5;
        return asin(TS*(1-x/DAB)*2/r/DOA)*r*r*0.5+TS*x/DAB;
    }
    else if(DOB >= r && DOA < r) {
        double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB;
        double TS = Cross(OA,OB)*0.5;
        return asin(TS*(1-y/DAB)*2/r/DOB)*r*r*0.5+TS*y/DAB;
    }
    else if(fabs(Cross(OA,OB)) >= r*DAB || Dot(AB,AC) <= 0 || Dot(BA,BC) <= 0) {
        if(Dot(OA,OB) < 0){
            if(Cross(OA,OB) < 0) return (-acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5;
            else return ( acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5;
        }
        else return asin(Cross(OA,OB)/DOA/DOB)*r*r*0.5;
    }
    else {
        double x = (Dot(BA,BC)+sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB;
        double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB;
        double TS = Cross(OA,OB)*0.5;
        return
(asin(TS*(1-x/DAB)*2/r/DOA)+asin(TS*(1-y/DAB)*2/r/DOB))*r*r*0.5 + TS*((x+y)/DAB-1);
    }
}

int main()
{
	int n,m,i,p,q,j;
	Circle C;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%lf%lf",&point[i].x,&point[i].y);
	}
	for(i=0;i<n;i++)
	{
		cpoint[i]=point[n-1-i];
	}
	point[n]=point[0];
	cpoint[n]=cpoint[0];
	double area=fabs(areaofp(n));
	//printf("%lf\n",area);
	scanf("%d",&m);
	for(j=1;j<=m;j++)
	{
		scanf("%lf%lf%d%d",&C.c.x,&C.c.y,&p,&q);
		double aim=area*(1.0-1.0*(double)p/(1.0*(double)q));
		//printf("%lf\n",aim);
		double left=0,right=1e6,mid;
		double out;
		while(true)
		{
			mid=(left+right)/2;
			C.r=mid;
			if(fabs(left-right)<1e-8)break;
			double ans = 0.0;
	        for(i=0;i<n;i++)
	            ans += TriAngleCircleInsection(C, point[i], point[i+1]);
	        //printf("%lf %lf %lf %lf\n",ans,mid,left,right);
	        if(fabs(ans)<aim)left=mid;
	        else right=mid;
	    }
	    left=0;
		right=1e6;
		out=mid;
		//printf("%lf\n",out);
		while(true)
		{
			mid=(left+right)/2;
			C.r=mid;
			if(fabs(left-right)<1e-8)break;
			double ans = 0.0;
	        for(i=0;i<n;i++)
	            ans += TriAngleCircleInsection(C, cpoint[i], cpoint[i+1]);
	        //printf("%lf %lf %lf %lf\n",ans,mid,left,right);
	        if(fabs(ans)<aim)left=mid;
	        else right=mid;
	    }
	    printf("%.7lf\n",max(out,mid));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/njupt_lyy/article/details/81255783