牛客练习赛41

B题:https://ac.nowcoder.com/acm/contest/373/B

分析:一个简单的计数dp,比赛时居然在dfs...

状态转移dp[i][j]=dp[i-1][j-a[i]]+dp[i-1][-j],dp[i][j]表示第i回合分数为j,由于有-j,可把分数整体加上一个大数k,并且由于空间不够要用滚动数组,特判去掉666的情况。

Ac code:

#include
using namespace std;
typedef long long ll;
ll dp[2][300*1500];
int a[305];
int n;
const int k=700*305;
const ll mod=1e8+7;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    dp[0][k]=1;
    for(int i=1;i<=n;i++)
        for(int j=-666*n;j<=666*n;j++){
          if(j==666) continue;
          dp[i&1][j+k]=(dp[(i-1)&1][j-a[i]+k]+dp[(i-1)&1][-j+k])%mod;
      }
    printf("%lld\n",dp[n&1][-666+k]);
    return 0;
} 

题目:https://ac.nowcoder.com/acm/contest/373/C

分析:一个简单的计数并查集

Ac code:

#include
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int parent[maxn];
ll a[maxn];
void init(int n)
{
	for(int i=1;i<=n;i++)
	  parent[i]=i;
}
int fnd(int x)
{
	return parent[x]!=x?parent[x]=fnd(parent[x]):x;
}
vectorans;
bool cmp(ll a,ll b)
{
	return a>b;
}
int main()
{
	int n,m,v;
	scanf("%d%d",&n,&m);
	init(n);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++){
		scanf("%d",&v);
		int fx=fnd(i),fy=fnd(v);
		if(fx!=fy)
		  parent[fy]=fx,a[fx]+=a[fy];///父亲加上儿子拥有的数量
	}
	for(int i=1;i<=n;i++)
	  if(i==parent[i])
	     ans.push_back(a[i]);
	sort(ans.begin(),ans.end(),cmp);
	ll sum=0;
	for(int i=0;i

题目:https://ac.nowcoder.com/acm/contest/373/D

分析:维护一个差异度d数组,把n个字符串作为起点,每个字符串的每个二进制位翻转,将d[i]维护成最小,则相似度为m-d[i]最大,求2^m个状态下的最小值

Ac code:

#include
using namespace std;
queueq;
int d[2000005];
int main()
{
	int n,m;
	char s[25];
	scanf("%d%d%*c",&n,&m);
	for(int i=0;i<(1<d[cur]+1){///维护d为最小差异度,m-d[i]就是最大了 
		  		d[nex]=d[cur]+1;
		  		q.push(nex);
			}
		}
	}
	int ans=40;
	for(int i=0;i<(1<

题目:https://ac.nowcoder.com/acm/contest/373/E

分析:纯公式题,球冠的体积:V=pi*h*h*(R-h/3)=pi*h*(3*r*r+h*h)/6

其中h为球冠的高,即垂直于截面的直径,R为球的半径,r为截面圆的半径。

补充公式:球冠表面积S=2*pi*R*h

Ac code:

#include
using namespace std;
const long double pi=4.0*atan(1.0); 
long double getv(long double R,long double h)
{
	return pi*h*h*(R-h/3.0);
}
int main()
{
	long double x1,y1,z1,x2,y2,z2,R,r;
	scanf("%Lf%Lf%Lf%Lf%Lf%Lf%Lf%Lf",&x1,&y1,&z1,&R,&x2,&y2,&z2,&r);
	long double h=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
	if(R=h){
		printf("%.7Lf\n",4.0/3*pi*R*R*R);
		return 0;
	}
	if(R+r<=h){
		return 0*printf("%.7Lf\n",pi*4.0/3*(R*R*R+r*r*r));
	}
	long double x=(R*R-r*r+h*h)/(2*h);
	long double v1=getv(R,x+R);
	long double v2=getv(r,r+h-x);
	long double ans=v1+v2;
	printf("%.7Lf\n",ans);
	return 0;
}

 

你可能感兴趣的:(杂文)