1002 Blow up the Enemy
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6803
题意:
给出一系列武器,每个武器有两个属性,伤害A和延迟D,张三和father的选择互不干扰,每个武器被选中的概率都是一样的,当他们的同时击败对方时,均有50%的可能性获胜。他们的血量HP最开始都为100,问张三击败father的最大概率。
题解:
其实就是计算出每个武器清空对方血槽所需的时间,而张三就是挑出时间消耗最少的武器时,此时的概率最大,遍历farther的选择就行了。
注意:
并不需要考虑张三的每一种情况,直接假设拿到最好的武器就好了。(我就是想多了,,,)
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; struct node{ int A; int D; int time; }Weapon[1005]; bool cmp(node a,node b) { return a.time<b.time; } int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n);//武器个数 memset(Weapon,0,sizeof(Weapon)); for(int i=1;i<=n;i++) { scanf("%d%d",&Weapon[i].A,&Weapon[i].D);//伤害和延迟 Weapon[i].time=100/Weapon[i].A; if(100%Weapon[i].A==0)Weapon[i].time--; Weapon[i].time*=Weapon[i].D;//消灭对手所需的时间; } sort(Weapon+1,Weapon+n+1,cmp); double pro; int x=Weapon[1].time,num=1; for(int i=2;i<=n;i++) { if(Weapon[i].time!=x){break;} else num++; } pro=1.0*num/n*0.5+(n-num)*1.0/n; printf("%lf\n",pro); } return 0; }
1004 Deliver the Cake
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6805
题意:
张三同学从s到达t,同时手提蛋糕,在路上会切换左右手,但是某些路会规定左右手,必须使用对应的左右手,而每切换一次就需要x秒的时间,问张三最快需要消耗多少秒的时间
题解:
先分别统计左右手, (如:u,v,w u0,u1,v0,v1,若他们的下标不同则需要加上x )再直接Dijkstra算法统计整个的路径就好了。
代码:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int inf=9999999; const int maxn=100005,maxv=2*maxn; ll dis[maxv][2]; char str[maxv]; struct Edge{int v,w;}; struct node{ ll d; int u,t; bool operator<(const node &n)const{return d>n.d;}//按照d从大到小排序 }; priority_queue<node> pq;//这样的排序就是按照d从小到大来排 vector<Edge>edge[maxv]; int main() { int T,n,m,s,t,x,u,v,w; for(scanf("%d",&T);T--;) { scanf("%d%d%d%d%d",&n,&m,&s,&t,&x); scanf("%s",str+1);//从1开始存 for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); edge[u].push_back(Edge{v,w}); edge[v].push_back(Edge{u,w});//同时进行存储 } for(int i=1;i<=n;i++) dis[i][0]=dis[i][1]=1e18; if(str[s]!='L')pq.push({dis[s][1]=0,s,1});//走左边 if(str[s]!='R')pq.push({dis[s][0]=0,s,0});//走右边 while(!pq.empty()) { node d=pq.top();pq.pop(); if(dis[d.u][d.t]<d.d)continue;//dis表示的就是已经记录了最短路径表示从s->d.u,不需要这条路 if(d.u==t)break;//已经到达了终点 for(const Edge &e:edge[d.u])//vector的迭代器//d.u->对应的多个终点 { ll w=e.w+d.d;// int t=str[e.v]=='R'?1:(str[e.v]=='L'?0:d.t); if(t==d.t&&w<dis[e.v][t])//不换手 pq.push(node{dis[e.v][t]=w,e.v,t}); w+=x; if(str[e.v]=='M')t=!t; if(t!=d.t&&w<dis[e.v][t]) pq.push(node{dis[e.v][t]=w,e.v,t}); } } printf("%lld\n",min(dis[t][0],dis[t][1])); while(!pq.empty())pq.pop(); for (int i = 1; i <= n; i++) edge[i].clear(); } return 0; }
1005 Equal Sentences
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6806
题意:
就是给定一连串个单词,相邻<=1的两个不相同的单词可以进行交换(自身和自身交换也行),问一共有多少组交换方法
题解:
运用递推,比如说1,2 交换 1个;2,3交换 1个;3,4交换 就有2个(加上1,2的那个)
f[i]=f[i-1]+f[i-2]->斐波那契数列
注意:
注意自己和自己交换的情况,也就是初始的即为1.
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=100005,mod=1e9+7; int f[N];string str[N]; int main() { int T,n; scanf("%d",&T); while(T--) { cin>>n; for(int i=1;i<=n;i++) { cin>>str[i]; } memset(f,0,sizeof(f)); f[0]=1; for(int i=1;i<=n;i++) { f[i]=f[i-1]; if(str[i]!=str[i-1]&&i>=2) { f[i]=(f[i-2]+f[i])%mod; } } printf("%d\n",f[n]); } return 0; }
1011 Kindergarten Physics
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6812
题意:
两个小球同时下落,求他们之间的距离
题解:
cin,cout
注意:人类迷惑行为,是在下输了。
代码:
#include<iostream> #include<cstdio> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int a,b,d,t; scanf("%d%d%d%d",&a,&b,&d,&t); printf("%d\n",d); } return 0; }