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