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;
}