来源:2016day2
分数:70+65+100
估分:100+65+100
T1
反思
其实写了质因子分解而且写了好久。不过事实上写的是对的但是。把所有的2000都打成1000导致运行错误少了30。
T2
题意
有n条蚯蚓。每次都会把最长的一条切成两部分,比例为v:(u-v),前者向下取整,后者为原长减前者。除了被切的那一条,剩下所有的蚯蚓长度都会增加q。如果有蚯蚓长度一样,那么随便选择一条切。
现在这个人要切m次蚯蚓。求t,2t,3t…m-m%t次切的蚯蚓原长度是多少。
以及切完m次后剩下蚯蚓长度排t,2t,3t…(n+m)-(n+m)%t的长度是多少。
分析
一开始弄了个优先队列瞎搞不过复杂度一算就不对。不过还是水到65了。不过那边手写堆的似乎到了95…= =
首先其实可以发现蚯蚓肯定是从大到小切的。切出来的蚯蚓按比例分开的话,也是总大到小满足单调递减的。
一开始想着怎么快速的把新切出来的东西放进去的我还是too simple.这里首先先把原来的蚯蚓排一个序,然后开始切。每次切成两半都会满足单调递减,但是两半放在一起排来排去还是很麻烦。所以干脆的把他们存在两个队列里。
那么就是先给所有的蚯蚓排序,放在第一个队列里,然后每切掉一条蚯蚓,就把它分成两部分,放在第二和第三个队列里即可。
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define pb push_back
#define N 100005
#define M 7000005
#define inf 1000000007
using namespace std;
void read(int &x){
x=0; char c=getchar();
for (; c<'0'; c=getchar());
for (; c>='0'; c=getchar())x=(x<<3)+(x<<1)+(c^'0');
}
bool cmp(int x,int y){return x>y;}
int q1[N],q2[M],q3[M];
const int o=0;
int main(){
int n,m,q,u,v,t,i;
read(n); read(m); read(q); read(u); read(v); read(t);
for (i=0; i<N; i++)q1[i]=-inf;
for (i=1; i<=n; i++)read(q1[i]);
sort(q1+1,q1+n+1,cmp);
for (i=0; i<M; i++)q2[i]=q3[i]=-inf;
int l1=1,l2=1,l3=1,r2=0,r3=0,now=0;
for (i=1; i<=m; i++){
int res=-inf;
if (res<q1[l1])res=q1[l1];
if (res<q2[l2])res=q2[l2];
if (res<q3[l3])res=q3[l3];
// printf("res=%d\n",res);
if (i%t==0)printf("%d ",res+now);
int l=(1ll*res+now)*1ll*u/v,r=res+now-l;
now+=q;
q2[++r2]=l-now; q3[++r3]=r-now;
if (res==q1[l1])l1++;
else if (res==q2[l2])l2++;
else l3++;
}
printf("\n");
for (i=1; ; i++){
int res=-inf;
if (res<q1[l1])res=q1[l1];
if (res<q2[l2])res=q2[l2];
if (res<q3[l3])res=q3[l3];
if (res==-inf)return (o-o);
if (i%t==0)printf("%d ",res+now);
if (res==q1[l1])l1++;
else if (res==q2[l2])l2++;
else l3++;
}
printf("\n");
return 0;
}
T3
分析
其实就只是一个简单的状压DP。
我采用了先用
n3
求所有抛物线能炸到的猪。因为原点已经确定,然后再确定两个点就可以确定一条抛物线了。然后再来一下确认这条抛物线能炸到哪些猪。保存状态。
然
2n
的来枚举一下所有的状态向后转移就好了。
其实明明作为第三题却比第二题简单...你和day1是串通好的吗
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
#define pb push_back
#define eps (1e-9)
using namespace std;
void read(int &x){
x=0; char c=getchar();
for (; c<'0'; c=getchar());
for (; c>='0'; c=getchar())x=(x<<3)+(x<<1)+(c^'0');
}
const int o=0;
int dp[1<<19],q[19*19];
bool vis[1<<19],can[20];
double x[20],y[20];
inline void Min(int &x,int y){if (x>y)x=y;}
struct AC{double x,y;}A[20];
bool cmp(AC a,AC b){return a.x<b.x;}
int main(){
// freopen("angrybirds.in","r",stdin);
// freopen("angrybirds.out","w",stdout);
int t,n,m,i,j,k,h,s,tmp,num;
double a,b;
read(t);
for (; t; t--){
memset(dp,63,sizeof(dp)); memset(can,0,sizeof(can));
read(n); read(m); h=0;
for (i=0; i<n; i++)scanf("%lf%lf",&A[i].x,&A[i].y);
sort(A,A+n,cmp);
for (i=0; i<n; i++)x[i]=A[i].x,y[i]=A[i].y;
for (i=0; i<n; i++){
for (j=i+1; j<n; j++)if (fabs(x[i]-x[j])>eps){
if (x[i]*y[j]-x[j]*y[i]>-eps)continue;
a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j]));
b=(y[i]-a*x[i]*x[i])/x[i];
// printf("a=%.5f b=%.5f\n",a,b);
s=0;
for (k=0; k<n; k++)if (fabs(a*x[k]*x[k]+b*x[k]-y[k])<eps)can[k]=1,s|=1<<k;
if (!vis[s])vis[s]=1,q[h++]=s;
// printf("s=%d\n",s);
}
if (!can[i]){vis[1<<i]=1,q[h++]=1<<i;}
}
tmp=1<<n; dp[0]=0;
for (i=0; i<tmp; i++){
num=dp[i]+1;
for (j=0; j<h; j++)Min(dp[i|q[j]],num);
}
printf("%d\n",dp[tmp-1]);
for (i=0; i<h; i++)vis[q[i]]=0;
}
return 0;
}