肇庆学院"菜鸟杯"程序设计竞赛2019(同步赛)部分解题(三)
这一部分自己一开始做的时候没想出来(有点菜)
然后学习着其他大神的代码自己理解了,来补上
I-师姐我想要红包!
链接:https://ac.nowcoder.com/acm/contest/3402/I
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
盼啊,盼啊,伴随着时钟的敲响,我们即将迎来了美好的传统佳节-春节。为了给新年增添浓浓节日气息,师弟师妹们纷纷向师姐说:“师姐我想要收大红包!”,而我们人美心善声音靓的jx师姐也很大气地说:“给,给大个的,n个够吗?”,师弟师妹:“够了,谢谢师姐,师姐真好。”,但是可爱调皮的师姐将总共n个红包给藏在了实验室228里,并给了你每个红包的坐标。机智的你当然是得拿走所有红包,但是你得移动最少的距离来拿到所有红包!!奥里给!!一开始你在(0,0)处。
输入描述:
第一行包含一个整数n(0<=n<=13)
接下来n行,每行2个实数,
表示第i个红包的坐标x,y(0<=|x|,|y|<=30)
两点之间的距离公式为
sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
输出描述:
需要走的最少距离,结果保留小数点后2位。
示例1
输出
复制4.58
解题思路:
这一题就是简单状压dp,模板题吧
因为题目的n并没有开的很大,所以自己手动算一下所有路径的长度不是很麻烦
ps:状压dp都不会!太菜了!虽然这题锵锵看懂,但是还是要补一点其他的题目来巩固一下自己对状压dp的理解
代码如下:
1 #include<bits/stdc++.h> 2 #include<cstdio> 3 #include<cstdlib> 4 using namespace std; 5 6 const int maxn=1005; 7 typedef long long ll; 8 int n; 9 const int inf=0x3f3f3f3f; 10 11 struct points 12 { 13 double x,y; 14 }a[15]; 15 16 double getlen(int i,int j) 17 { 18 return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); 19 } 20 21 double dis[15][15]; 22 double dp[1<<15][15]; 23 24 int main() 25 { 26 27 while(cin>>n) 28 { 29 a[0].x=0;a[0].y=0; 30 for(int i=1;i<=n;++i) 31 { 32 cin>>a[i].x>>a[i].y; 33 } 34 35 for(int i=0;i<=n;++i) 36 { 37 for(int j=i+1;j<=n;++j) 38 { 39 dis[i][j]=dis[j][i]=getlen(i,j); 40 } 41 } 42 n++; 43 for(int i=0;i <= 1<<n;++i) 44 { 45 for(int j=0;j<=n;++j) 46 { 47 dp[i][j]=inf; 48 } 49 } 50 dp[1][0]=0; 51 for(int i=1;i< 1<<n;++i) 52 { 53 for(int j=0;j<n;++j) 54 if(i>>j&1) 55 { 56 for(int k=0;k<n;++k) 57 { 58 if((i^1<<j)>>k&1) 59 { 60 dp[i][j]=min(dp[i][j],dp[i^1<<j][k]+dis[k][j]); 61 } 62 } 63 } 64 } 65 66 double ans=inf; 67 for(int i=0;i<n;++i) 68 { 69 ans=min(ans,dp[(1<<n)-1][i]); 70 } 71 printf("%.2f\n",ans); 72 } 73 return 0; 74 }
B-麻烦的杰西
链接:https://ac.nowcoder.com/acm/contest/3402/B
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
圣诞节那一天,杰西收到一个圣诞蛋糕,不过这个蛋糕有点参差不齐,具体地说这个蛋糕是由n个小蛋糕拼起来的,每个小蛋糕长度为1,宽度为1,高度为hi。这对于“精致”的杰西来说是不能容忍的,所以她决定来“横切”蛋糕。具体地说:圣诞蛋糕放在水平面上,杰西先沿某一高度水平横切过去,再留下相同高度并连续的小蛋糕们。也就是她会把不同高度的小蛋糕和虽然同一高度但与被留下的小蛋糕们不连续的小蛋糕扔掉。杰西不想浪费太多蛋糕,所以她想尽可能多地留下小蛋糕。
请问杰西最多能留下多少体积的蛋糕和对应的蛋糕高度是多少?若横切后(当然也可以不横切),出现多个体积相同的蛋糕,杰西不需要得到高度最高的蛋糕,而是直接留下更靠左的蛋糕。
输入描述:
多测试用例,用例数不超过10组
每个测试用例,第一行为一个正整数n(n<=100000)
第二行有n个整数hi代表每个小蛋糕的高度(1<=hi<=1000000000 )
输出描述:
输出占一行。俩个整数H和C用空格隔开,分别代表被杰西留下的最多的小蛋糕的高度和总体积。
示例1
说明
如图很明显选择橙色部分的蛋糕是杰西所能留下高度为7的最大体积的蛋糕了:7*(1+1+1)*1=21。
所以杰西会在高度为7的水平面切一刀,留下橙色部分的蛋糕,其他蛋糕均扔掉。
解题思路:
这一题实在是蠢了,看了别人的代码一下子就理解了
这说明这一题和上一题不一样,上一题是知识点没掌握,这一题就是自己确实是没想到
其实这一题和算ZQU那一题还是挺像的,就是先处理,然后再计算
把每一根柱子能延伸的最左和最右分别求出来,然后计算其能代表的最大值
也可能是做题的时候看上一题看的烦躁了,心也就没能静下来好好的思考这一题的解题方法
所以,还是要把心静下来,真的要认真的去分析每一道题,也不能因为其他的题而烦躁
其实之前期末复习的时候也是这样,一旦烦躁了,就什么也看不进去,什么也学不进去了
保持良好的心态,才能使自己的效率提高,使思路更加的清晰
(写了一大堆废话)
代码如下:
1 #include<stdio.h> 2 #include<string.h> 3 long long l[500005]; 4 long long r[500005]; 5 long long n[500005]; 6 int main() 7 { 8 int N; 9 long long sum = 0; 10 while (~scanf("%d",&N)) 11 { 12 sum = 0; 13 for (int i = 0; i < 500005; i++) { 14 l[i] = r[i] = n[i] = 0; 15 } 16 for (int i = 1; i <= N; i++) 17 scanf("%lld", &n[i]); 18 n[0] = 0; 19 n[N + 1] = 0; 20 int k,i; 21 for (i = 1; i <= N; i++) 22 { 23 k = i - 1; 24 while (n[i] <= n[k]) 25 { 26 k = l[k] - 1; 27 } 28 l[i] = k + 1; 29 } 30 for (i = N; i >= 1; i--) 31 { 32 k = i + 1; 33 while (n[i] <= n[k]) 34 { 35 k = r[k] + 1; 36 } 37 r[i] = k - 1; 38 } 39 long long nnn = 1; 40 for (i = 1; i <= N; i++) 41 { 42 if ((r[i] - l[i] + 1) * n[i] > sum) { 43 sum = (r[i] - l[i] + 1) * n[i]; 44 nnn = n[i]; 45 } 46 } 47 printf("%lld %lld\n", nnn, sum); 48 } 49 return 0; 50 }
ps:还有一题E暂时不想弄了
学画画去了(不务正业)