2014 Multi-University Training Contest 7 题解
来源:互联网 发布:软件开发专业就业方向 编辑:程序博客网 时间:2024/06/05 22:43
<a target=_blank href="http://acm.hdu.edu.cn/showproblem.php?pid=4939"></a>http://acm.hdu.edu.cn/showproblem.php?pid=4939
HDU 4939题解
题意:
1.红塔,每单位时间造成x的伤害
2.绿塔,在经过之后每单位时间造成y的伤害
3.蓝塔,在经过之后每走一单位距离需要多花z的时间
题解:
显然,红塔肯定放在最后面。绿塔和蓝塔就进行DP求解。dp[i][j]表示前i个塔有j个塔是绿塔时,造成的最大伤害。同时以剩下的n-i个全为红塔,来求出最大伤害ans。
#include<stdio.h>http://blog.csdn.net/lyhvoyage/article/details/38533545#include<string.h>#include<math.h>#include<algorithm>#define LL long long int#define MAX 1600using namespace std;LL dp[3][MAX];int main(){ LL T,n,x,y,z,t; LL ans=0,best; while(~scanf("%I64d",&T)){ for(int cas=1;cas<=T;cas++){ scanf("%I64d %I64d %I64d %I64d %I64d",&n,&x,&y,&z,&t); ans=n*t*x; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ int cur=i%2; int pas=(i+1)%2; dp[cur][0]=0; best=(i*z+t)*x*(n-i);//注意这个地方也需要处理,开始我就搞忘了 if(best>ans) ans=best; for(int j=1;j<=i;j++){//表示持续伤害的塔的个数 if(j==i) {//i==j时要特殊处理,dp[i-1][i]这种状况不存在。只能是从dp[i-1][i-1]到dp[i][i] dp[cur][j]=(dp[pas][j-1]+((i-j)*z+t)*(j-1)*y); }else { dp[cur][j]=max((dp[pas][j]+((i-j-1)*z+t)*(j*y)),(dp[pas][j-1]+((i-j)*z+t)*(j-1)*y)); } best=dp[cur][j]+(n-i)*(x+j*y)*((i-j)*z+t); if(best>ans) ans=best; } } printf("Case #%d: %I64d\n",cas,ans); } } return 0;}
计算机在做四则运算的时候,括号,加减乘除法的优先顺序也和笔算的优先级是一样的?(忘大牛指点)
开始n,x,y,z,t是int型的,在计算的过程中爆int了,我就进行了一下强转。
在什么地方开始转的呢?
按照四则运算的优先级的顺序算的时候,什么地方可能开始爆int,就把它转成Long Long int,
在后面计算的过程中,编译器会自动把int转化为long long int进行运算。
最后AC掉了
计算机进行四则运算的优先级和人是一样的。要是强转的话,就转优先级最高处就好啦?
#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#define LL long long int#define MAX 1600using namespace std;LL dp[3][MAX];int main(){ int T,n,x,y,z,t; LL ans=0,best; while(~scanf("%d",&T)){ for(int cas=1;cas<=T;cas++){ scanf("%d %d %d %d %d",&n,&x,&y,&z,&t); ans=(LL)n*t*x; memset(dp,0,sizeof(dp)); for(int i=0;i<MAX;i++){ dp[0][i]=0; dp[1][i]=0; } for(int i=1;i<=n;i++){ int cur=i%2; int pas=(i+1)%2; dp[cur][0]=0; best=(i*z+t)*(LL)x*(n-i); if(best>ans) ans=best; for(int j=1;j<=i;j++){//表示持续伤害的塔的个数 if(j==i) { dp[cur][j]=(dp[pas][j-1]+((i-j)*(LL)z+t)*(j-1)*y); }else { dp[cur][j]=max((dp[pas][j]+((i-j-1)*(LL)z+t)*(j*y)),(dp[pas][j-1]+((i-j)*(LL)z+t)*(j-1)*y)); } best=dp[cur][j]+(n-i)*((LL)x+j*y)*((i-j)*z+t); if(best>ans) ans=best; } } printf("Case #%d: %I64d\n",cas,ans); } } return 0;}
http://acm.hdu.edu.cn/showproblem.php?pid=4941
HDU 4941 Magical Forest
题意:
N*M的矩阵,有K(10^5)个位置上有水果,交换行或者列T(10^5)次。
比赛的时候,我们用的STL的map和vector一起做的。
map的key代表的是横坐标或者纵坐标,value表示的是vector的下标。这样vecor实际占的内存不会超过10^5的int。
在交换两行或者两列的时候,会修改vector[i].szie()的时间复杂度。
感觉这个做法的时间复杂度在n(10^5)-n^2之间,着看他的数据的坑爹程度了,正常的复杂度应该在10^5-10^6之间吧。
http://blog.csdn.net/lyhvoyage/article/details/38533545 可参考
#include<stdio.h>#include<map>#include<iostream>#include<vector>#define MAX 100009using namespace std;struct node {int x;int y;int w; }a[MAX];map <int ,int>map1;map <int ,int>map2;map<int, int>::iterator iter,iter1,iter2;vector <int> vector1[MAX];vector <int> vector2[MAX];int main(){int T,N,M,K,Q;while(~scanf("%d",&T)){for(int t=1;t<=T;t++){map1.clear();map2.clear();for(int i=0;i<MAX;i++)vector1[i].clear();for(int i=0;i<MAX;i++)vector2[i].clear();printf("Case #%d:\n",t);scanf("%d %d %d",&N,&M,&K);for(int i=0;i<K;i++){scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].w);if(map1.find(a[i].x)==map1.end()){map1[a[i].x]=i;vector1[i].push_back(i);}else{iter=map1.find(a[i].x);int tmp=iter->second;vector1[tmp].push_back(i);}if(map2.find(a[i].y)==map2.end()){map2[a[i].y]=i;vector2[i].push_back(i);}else{iter=map2.find(a[i].y);int tmp=iter->second;vector2[tmp].push_back(i);}}scanf("%d",&Q);int x1,x2,flag;for(int i=0;i<Q;i++){scanf("%d %d %d",&flag,&x1,&x2);if(flag==1){if(map1.find(x1)==map1.end()) continue;iter1=map1.find(x1);iter2=map1.find(x2);int tmp1=iter1->second;int tmp2=iter2->second;int cc1=vector1[tmp1].size();int cc2=vector1[tmp2].size();for(int j=0;j<cc1;j++){a[vector1[tmp1][j]].x=x2;}for(int j=0;j<cc2;j++){a[vector1[tmp2][j]].x=x1;}vector1[tmp1].swap(vector1[tmp2]);}if(flag==2){if(map2.find(x1)==map2.end())continue;iter1=map2.find(x1);iter2=map2.find(x2);int tmp1=iter1->second;int tmp2=iter2->second;int cc1=vector2[tmp1].size();int cc2=vector2[tmp2].size();for(int j=0;j<cc1;j++){a[vector2[tmp1][j]].y=x2;}for(int j=0;j<cc2;j++){a[vector2[tmp2][j]].y=x1;}vector2[tmp1].swap(vector2[tmp2]);}if(flag==3){bool ok=false;iter=map1.find(x1);int tmp=iter->second;int siz=vector1[tmp].size();for(int j=0;j<siz;j++){int cc=vector1[tmp][j];if(a[cc].y==x2) {ok=true;printf("%d\n",a[vector1[tmp][j]].w);break;}}if(ok==false) printf("0\n");}}}}return 0;}/*4 4 161 1 11 2 21 3 31 4 42 1 52 2 62 3 72 4 83 1 93 2 103 3 113 4 124 1 134 2 144 3 154 4 1661 1 22 1 23 2 23 3 23 3 51 1 11 3 22 1 32 2 43 3 55*/
HDU 4937 Lucky Number 题解
题意:
Love_Kid将3,4,5,6认为是幸运数字。给定一个十进制数n。现在可以讲起任意转换成其他进制,但转换后的数必须是由3,4,5,6构成的,而这个进制称为幸运进制。问有多少个幸运进制。若有无数个,则输出-1。例如19在5进制下是34,所以5是幸运进制。
题解:
本题转化成一元二次方程来解题也是很妙的想法。
#include<stdio.h>#include<math.h>#define LL long long int#define INF 7009int main(){ LL T,n,ans; while(~scanf("%I64d",&T)){ for(LL cas=1;cas<=T;cas++){ scanf("%I64d",&n); ans=0; if(n>=3&&n<=6){ printf("Case #%I64d: -1\n",cas); continue; } for(LL i=3;i<=6;i++){ for(LL j=3;j<=6;j++){ if((n-i)/j>i&&(n-i)/j>j&&(n-i)%j==0){//解一次方程 ans++; } } } for(LL i=3;i<=6;i++){ for(LL j=3;j<=6;j++){ for(LL k=3;k<=6;k++){ LL a=i; LL b=j; LL c=k-n; LL tmp=sqrt(b*b-4*a*c); if(tmp*tmp!=b*b-4*a*c) continue;//说明灯儿塔(b^2-4*a*c)是否为整数 if((tmp-b)%(2*a)!=0) continue;//说明base是不是整数.如果 a,b,c为这种组合时,base没有整数解 LL base=(tmp-b)/(2*a); if(base>i&&base>j&&base>k) ans++; } } } for(LL i=4;i*i*i<=n;i++){//i*i*i限制了,肯定是大于等于4位的 LL tmp=n; while(tmp%i<i&&tmp%i>=3&&tmp%i<=6){ tmp=tmp/i; } if(!tmp) ans++; } printf("Case #%I64d: %I64d\n",cas,ans); } } return 0;}
- 2014 Multi-University Training Contest 7 题解
- 2014 Multi-University Training Contest 8题解
- 2014 Multi-University Training Contest 1 题解
- 2014 Multi-University Training Contest 7小记
- 2014(高斯消元 DP 数论)Multi-University Training Contest 1 题解
- 2014 Multi-University Training Contest 9 题解&&总结
- 2016 Multi-University Training Contest 7题解报告
- 2016 Multi-University Training Contest 4 题解
- 2016 Multi-University Training Contest 5 题解
- 2016 Multi-University Training Contest 8 题解
- 2014 Multi-University Training Contest 3 简要题解 by——Fudan University
- 2014 Multi-University Training Contest 3 简要题解 by——Fudan University
- hdu 4937 Lucky Number 2014 Multi-University Training Contest 7
- hdu 4941 Magical Forest--2014 Multi-University Training Contest 7
- hdu 4941 Magical Forest 2014 Multi-University Training Contest 7
- hdu 4941 2014 Multi-University Training Contest 7 1007
- 2014 Multi-University Training Contest 7——by UESTC
- 2014 Multi-University Training Contest 7 1003 1005
- HDU 1698 Just a Hook (线段树区间更新)
- Python repr str 函数
- 设计模式 之 原型模式
- 存在心里的人,走进生命的魂
- do not back up IOS被拘处理
- 2014 Multi-University Training Contest 7 题解
- 黑马程序员——集合框架类学习
- STRONGSWAN源代码学习2_LIBGCRYPT
- 遍历删除.svn .git .repo目录
- qsort函数学习总结
- HDU 4771
- 算法的特征及设计要求
- MySQL常用命令(持续总结中)
- sum 3- 4