UPC2018组队训练赛第七场

题目来自ICPC 2017 Japan Tsukuba


A题:Secret of Chocolate Poles

有三种巧克力,分别是厚度为1的白色巧克力,厚度为1或者k的黑色巧克力。要求把巧克力放到高度为 l 的盒子里,并且要黑白相间,底部和顶部必须都是黑色的

当l=1,ans=1;当l<k,ans=(l-1)/2+1;当l=k,ans=(l-1)/2+2;当l>k时,就可以转化成排列组合问题了,枚举厚度为k的黑色巧克力数目i,然后对于每一种情况,再枚举厚度为1的黑色巧克力的数目j,那么此时排列的情况就是(i+j)! / ( i! * j! )。最后取和就行了。

因为阶乘会爆longlong,所以就用java写的

 1 import java.util.*;
 2 import java.math.BigInteger;
 3 public class Main {
 4
 5     public static void main(String[] args) {
 6         // TODO Auto-generated method stub
 7         Scanner cin = new Scanner(System.in);
 8         BigInteger[]fac=new BigInteger[60];
 9         fac[0]=BigInteger.valueOf(1);
10         BigInteger tmp;
11         for(int i=1;i<60;i++) {
12             tmp=BigInteger.valueOf(i);
13             fac[i]=fac[i-1].multiply(tmp);
14         }
15         int l,k;
16         l= cin.nextInt();
17         k=cin.nextInt();
18         int flag=0;
19         long aa=0;
20         BigInteger ans=BigInteger.valueOf(0);
21         if(l==1)    aa=1;
22         else if(l<k) aa=(l-1)/2+1;
23         else if(l==k)   aa=(l-1)/2+2;
24         else
25         {
26             flag=1;
27             BigInteger tt,pp;
28             for(int i=0;i*(k+1)<=(l-1);i++)
29             {
30                 for(int j=0;j*2<=(l-1-i*(k+1));j++)
31                 {
32                     tt=fac[i].multiply(fac[j]);
33                     pp=fac[i+j].divide(tt);
34                     ans=ans.add(pp);
35                 }
36             }
37             for(int i=0;i*2<=(l-k);i++)
38             {
39                 for(int j=0;j*(k+1)<=(l-k-i*2);j++){
40                     tt=fac[i].multiply(fac[j]);
41                     pp=fac[i+j].divide(tt);
42                     ans=ans.add(pp);
43                 }
44             }
45         }
46         if(flag==1)
47             System.out.println(ans);
48         else
49         {
50             ans=BigInteger.valueOf(aa);
51             System.out.println(ans);
52         }
53
54     }
55
56 }

之后看了大佬的代码https://www.cnblogs.com/clrs97/p/8537178.html  发现可以用dp

f[i][j]代表高度为i,顶层颜色为j的方案数。(j=0,表示黑色,j=1表示白色)

 1 #include<cstdio>
 2 typedef __int128 lll;
 3 const int N=200;
 4 lll f[N][2],ans;//dark white
 5 int l,k,i;
 6 void write(lll x){
 7     if(x>=10)write(x/10);
 8     x%=10;
 9     printf("%d",(int)(x));
10 }
11 int main(){
12     scanf("%d%d",&l,&k);
13     f[1][0]++;
14     f[k][0]++;
15     for(i=1;i<=l;i++){
16         f[i+1][1]+=f[i][0];
17         f[i+1][0]+=f[i][1];
18         f[i+k][0]+=f[i][1];
19     }
20     for(i=1;i<=l;i++)ans+=f[i][0];
21     write(ans);
22 }


B题:Parallel lines

给偶数个点,两点形成直线,保证任意三点不在同一条直线,问最多能找到多少对平行线

写个搜索,找到所有的直线的可能情况,然后用vector存直线的两点,之后遍历找平行线。找平行线的话,可以用向量

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 struct node
 5 {
 6     int x,y;
 7 } Point[20];
 8 int n,ans=-1;
 9 bool vis[20];
10 vector<pair<int,int> >line;
11 void countt()
12 {
13     int tmp=0;
14     for(int i=0; i<line.size(); i++)
15     {
16         int x1=Point[line[i].first].x-Point[line[i].second].x;
17         int y1=Point[line[i].first].y-Point[line[i].second].y;
18         for(int j=i+1; j<line.size(); j++)
19         {
20             int x2=Point[line[j].first].x-Point[line[j].second].x;
21             int y2=Point[line[j].first].y-Point[line[j].second].y;
22             if(x1*y2==x2*y1)
23             {
24                 tmp++;
25             }
26         }
27     }
28     ans=max(ans,tmp);
29 }
30 void dfs(int now)
31 {
32     if(now==n+1)
33     {
34         countt();
35         return;
36     }
37     if(vis[now])
38     {
39         dfs(now+1);
40     }
41     else
42     {
43         for(int i=1; i<=n; i++)
44         {
45             if(vis[i]||i==now)
46             {
47                 continue;
48             }
49             line.push_back(make_pair(now,i));
50             vis[now]=vis[i]=1;
51             dfs(now+1);
52             line.pop_back();
53             vis[now]=vis[i]=0;
54         }
55     }
56 }
57 int main()
58 {
59     scanf("%d",&n);
60     for(int i=1; i<=n; i++)
61     {
62         scanf("%d %d",&Point[i].x,&Point[i].y);
63     }
64     dfs(1);
65     printf("%d\n",ans);
66     return 0;
67 }
68  


C题:Medical Checkup

有很多个窗口,有n个人,每个人去窗口办理业务的时间不同,问在t分钟时,每个人分别在哪个窗口

首先求一下每个人在第一个窗口待的时间,然后遍历每个人,如果t小于当前这个人在第一个窗口待的时间,直接输出1;否则,我们可以发现每个人在其他的窗口待的时间是相同的,如果当前这个人办理业务需要的时间小于他前一个人的,那么他在以后的每一个窗口所带的时间就是h[i]=h[i]+h[i-1]-h[i]=h[i-1],不小于的话就直接是他自己办理业务的时间h[i],对于每一个人,用 tt=t-sum[i] 表示这个人离开第一个窗口后还剩的时间,用 tt/h[i]+1,代表在tt这段时间里他能往后走多少个窗口,最后再加上第一个窗口(tt/h[i]+2)就是最终所在的窗口编号了。

 1
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=100050;
 5 int n;
 6 ll h[N],sum[N],t;
 7 int main()
 8 {
 9     scanf("%d %lld",&n,&t);
10     for(int i=1;i<=n;i++)
11     {
12         scanf("%lld",&h[i]);
13         sum[i]=sum[i-1]+h[i];
14     }
15     for(int i=1;i<=n;i++)
16     {
17         ll tt=t-sum[i];
18         if(tt<0)
19         {
20             printf("1\n");
21             continue;
22         }
23         else
24         {
25             if(h[i]<h[i-1])
26             {
27                 h[i]+=(h[i-1]-h[i]);
28             }
29             ll ans=tt/h[i];
30             ans+=2;
31             printf("%lld\n",ans);
32         }
33     }
34     return 0;
35 }



UPC2018组队训练赛第七场

原文地址:https://www.cnblogs.com/scott527407973/p/9556301.html

时间: 2024-10-09 12:30:55

UPC2018组队训练赛第七场的相关文章

2018年第四阶段组队训练赛第七场

A: Secret of Chocolate Poles 题目描述 Wendy, the master of a chocolate shop, is thinking of displaying poles of chocolate disks in the showcase. She can use three kinds of chocolate disks: white thin disks, dark thin disks, and dark thick disks. The thin

Contest1814 - 2019年我能变强组队训练赛第七场

Scores of Final Examination On-Screen Keyboard Tally Counters Balance Scale #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> using namespace std; typedef long long ll; unordered_map<ll,bool> m1; int n,m,cnt

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分相同,第一部分与第二部分对称. 现在给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法,求出以第i个点为中心的回文串长度,记录到数组p中 要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样. 因为我们已经记录下来以

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&amp;#39;s problem(manacher+二分/枚举)

pid=5371">HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称. 如今给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法.求出以第i个点为中心的回文串长度.记录到数组p中 要满足题目所要求的内容.须要使得两个相邻的回文串,共享中间的一部分,也就是说.左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也

HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第一种是行交换操作,就是把矩阵的两行进行交换,另一种是列交换操作,注意两种操作都要求行或列至少要有一个水果,第三种操作是查找,询问第A行B列的水果的能量值,如果查询的位置没有水果,则输出0. 因为n和m都很大,达到了2*10^9,但水果最多一共只有10^5个,我的做法是直接用结构体存了之后排序,然后m

第四阶段组队训练赛第六场( 题源:UKIEPC2017)

A: Alien Sunset 题目描述 Following tremendous advances in space flight control software and equally impressive innova- tions in reality TV crowdfunding, humans have successfully settled a number of planets, moons, asteroids, and various other kinds of fu

2018年第四阶段组队训练赛第三场(BAPC2017 Preliminaries)

D.Disastrous Doubling 题目描述 A scientist, E. Collie, is going to do some experiments with bacteria.Right now, she has one bacterium. She already knows that this species of bacteria doubles itself every hour. Hence, after one hour there will be 2 bacter

北方大学 ACM 多校训练赛 第七场 C Castle(LCA)

[题意]给你N个点,N条不同的边,Q次询问,求出u,v之间的最短路. [分析]题意很简单,就是求最短路,但是Q次啊,暴力DIJ?当然不行,观察到这个题边的数目和点的数目是相同的,也就是说这个图是由一棵树加了一条边而形成的.而对于一棵树,如果有Q次询问最短路,那就可以用LCA来做,复杂度QlogN,但是现在加了一条边,可能会使有些点之间的路径变短.假设多加的这条边的两个端点是U,V,那么对于询问的X,Y,有这么三种情况,直接过LCA,或者经过U,V,详情见代码. #include <bits/st

Contest1539 - 2019年我能变强组队训练赛第十一场

Greater New York 2012 Hailstone HOTPO #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { ll n; int T; cin>>T; while(T--) { ll k; scanf("%lld %lld&q