17-09-06模拟赛

T1:当横的切时,第i刀可以用直线y=b-√(i/n)*b表示。

竖着切时,考虑前((n-1)/2)刀,第i刀可以用直线y=√(i/2*n)*a表示。

当n为偶数时,第(n-1)/2+1刀可以用直线y=a/2表示。

后((n-1)/2)刀与前((n-1)/2)刀关于y=a/2对称。

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 inline int in(){
 7     int x=0;bool f=0; char c;
 8     for (;(c=getchar())<'0'||c>'9';f=c=='-');
 9     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
10     return f?-x:x;
11 }
12 int n,a,b,c;
13 double p[1002];
14 int main()
15 {
16     n=in();a=in();b=in();c=in();
17     if (!c){
18         for (int i=n-1;i;--i)
19         printf("%.10lf\n",(double)b-(double)(sqrt(i*1.0/n)*b));
20     }else{
21         for (int i=1;i<=(n-1)/2;++i)
22         p[i]=(double)a*(double)sqrt(i/(2.0*n)),printf("%.10lf\n",p[i]);
23         if (!(n&1)) printf("%.10lf\n",(double)a/2.0);
24         for (int i=(n-1)/2;i;--i) printf("%.10lf\n",(double)a-p[i]);
25     }return 0;
26 }

T2:二分k,对所有摊位物品此时的价格从小到大排序,枚举前k个物品的价格之和是否超过m。注意数据大小。时间复杂度O(n log2 n)

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ll long long
 5 #define MN 100005
 6 using namespace std;
 7 inline int in(){
 8     int x=0;bool f=0; char c;
 9     for (;(c=getchar())<'0'||c>'9';f=c=='-');
10     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
11     return f?-x:x;
12 }
13 int a[MN],b[MN],n,l,r,ans;
14 ll c[MN],m;
15 inline bool check(int k){
16     if (!k) return 1;ll sum=0ll;
17     for (int i=1;i<=n;++i) c[i]=1ll*b[i]*(k-1)+a[i];sort(c+1,c+n+1);
18     for (int i=1;i<=k;++i) {sum+=c[i];if (sum>m) return 0;}return 1;
19 }
20 int main()
21 {
22     scanf("%d%lld",&n,&m);
23     for (int i=1;i<=n;++i) a[i]=in(),b[i]=in();
24     l=0;r=n;while (l<=r){
25         int mid=(l+r)>>1;
26         if (check(mid)) ans=mid,l=mid+1;
27         else r=mid-1;
28     }printf("%d",ans);return 0;
29 }

 T3:考虑建立图论模型。

对bi的异或和求前缀和,从i向j连权值为sum[i]^sum[j]的边,表示由sum[i]求得sum[j]时所需要的话费为sum[i]^sum[j].

易知确定所有系数需要求出所有的sum值,所以对所有节点求最小生成树(MST)即可。

考虑到数据范围及图的特性,可以使用不加堆优化的Prim算法。时间复杂度为O(n2).

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define MN 10005
 5 using namespace std;
 6 inline int in(){
 7     int x=0;bool f=0; char c;
 8     for (;(c=getchar())<'0'||c>'9';f=c=='-');
 9     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
10     return f?-x:x;
11 }
12 int sum[MN],c[MN],n;
13 bool vis[MN];
14 long long ans=0ll;
15 int main()
16 {
17     n=in();sum[0]=0;
18     for (int i=1;i<=n;++i) c[i]=sum[i]=sum[i-1]^in();
19     for (int i=1;i<=n;++i){
20         int v=0;for (int j=1;j<=n;++j)
21         if (!vis[j]&&(!v||c[j]<c[v])) v=j;
22         vis[v]=1;ans+=1ll*c[v];
23         for (int j=1;j<=n;++j) c[j]=min(c[j],sum[j]^sum[v]);
24     }printf("%lld",ans);return 0;
25 }

 

posted on 2017-09-07 12:58  whz2002  阅读(113)  评论(0编辑  收藏  举报