1002 Blow up the Enemy
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6803
题意:
给出一系列武器,每个武器有两个属性,伤害A和延迟D,张三和father的选择互不干扰,每个武器被选中的概率都是一样的,当他们的同时击败对方时,均有50%的可能性获胜。他们的血量HP最开始都为100,问张三击败father的最大概率。
思路:
儿子肯定直接选价值最大的武器(即为最小次数打出100伤害),张三如果不选相同次数即可打出100伤害的武器就会输,所以我们统计武器中最快打出100伤害的武器的个数k,k/2n即为儿子输的概率,求儿子赢的概念为1−k/2
代码:
#include<iostream> #include<stdio.h> using namespace std; const int maxn=1010; int a[maxn],d[maxn]; int main() { int T,n; cin>>T; while(T--) { cin>>n; int cnt,ans; cnt=ans=0; for(int i=1;i<=n;i++) { cin>>a[i]>>d[i]; if(a[i]>=100)cnt++; } if(cnt) { double x=cnt*1.0/n*0.5; cout<<1-x<<endl; continue; } int mint=100/a[1]*d[1]; for (int i=1;i<=n;i++) { int k; if(100%a[i]==0)k=(100/a[i]-1)*d[i]; else k=100/a[i]*d[i]; if(mint>k) { mint = k; } } for(int j=1;j<=n;j++) { int kk=(mint/d[j]+1)*a[j]; if(kk>=100) { ans++; } } double xx=ans*1.0/n*0.5; cout<<1-xx<<endl; } return 0; }
1004 Deliver the Cake
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6805
题意:
张三同学从s到达t,同时手提蛋糕,在路上会切换左右手,但是某些路会规定左右手,必须使用对应的左右手,而每切换一次就需要x秒的时间,问张三最快需要消耗多少秒的时间
思路:
L和R可以考虑将换手造成的时间消耗放在边权上,对于M可以考虑将M分成L和R两条路(默认优先L)
然后自己跑Dijkstra就行,如果起点或者终点为M,需要创建边权为0的虚拟点代替
代码:
#include<cstring> #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #define ll long long #define P pair<ll,int> #define INF 0x3f3f3f3f using namespace std; const int N=2e5+10, M=2e6+10; int T,n,m,s,t,x; int to[M],nxt[M],val[M],head[N],idx; char c[N]; ll dis[N]; bool st[N]; inline void add(int a,int b,int c) { to[idx]=b,nxt[idx]=head[a],val[idx]=c,head[a]=idx++; } void dijkstra() { memset(st,false,sizeof st); memset(dis,INF,sizeof dis); priority_queue<P,vector<P>,greater<P>> heap; if(c[s]=='M') heap.push({0,0}), dis[0]=0; else heap.push({0,s}), dis[s]=0; while(heap.size()) { P t=heap.top(); heap.pop(); int id=t.second; if(st[id]) continue; st[id]=true; for(int i=head[id];~i;i=nxt[i]) { int j=to[i]; if(dis[j]>dis[id]+val[i]) { dis[j]=dis[id]+val[i]; heap.push({dis[j],j}); } } } } void solve(){ idx=0; memset(head,-1,sizeof head); scanf("%d%d%d%d%d",&n,&m,&s,&t,&x); scanf("%s",c+1); if(c[s]=='M') add(0,s,0), add(s,0,0), add(0,s+n,0), add(s+n,0,0); if(c[t]=='M') add(2*n+1,t,0), add(t,2*n+1,0), add(2*n+1,t+n,0), add(t+n,2*n+1,0); int u, v, val; for(int i=0; i<m; i++){ cin>>u>>v>>val; if(c[u]==c[v] && (c[u]=='R'||c[u]=='L')) add(u,v,val), add(v,u,val); else if(c[u]==c[v] && c[u]=='M') add(u,v,val), add(v,u,val), add(u+n,v,val+x), add(v,u+n,val+x), add(u,v+n,val+x), add(v+n,u,val+x), add(u+n, v+n, val), add(v+n, u+n, val); else if((c[u]=='L' && c[v]=='R')||(c[u]=='R'&&c[v]=='L')) add(u,v,val+x), add(v,u,val+x); else if(c[u]=='L' && c[v]=='M') add(u,v,val), add(v,u,val), add(u,v+n,val+x), add(v+n, u, val+x); else if(c[u]=='R' && c[v]=='M') add(u,v,val+x), add(v,u,val+x), add(u,v+n,val), add(v+n, u, val); else if(c[u]=='M' && c[v]=='L') add(u,v,val), add(v,u,val), add(u+n,v,val+x), add(v, u+n, val+x); else if(c[u]=='M' && c[v]=='R') add(u,v,val+x), add(v,u,val+x), add(u+n,v,val), add(v, u+n, val); } dijkstra(); if(c[t]=='M') cout<<dis[2*n+1]; else cout<<dis[t]; cout<<endl; } int main() { scanf("%d",&T); while(T--) solve(); return 0; }
1005 Equal Sentences
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6806
题意:
就是给定一连串个单词,相邻<=1的两个不相同的单词可以进行交换(自身和自身交换也行),问一共有多少组交换方法
思路:
因为位置之差不大于1,所以考虑交换相邻的两个单词来构造“几乎相等”(包括其本身)
在交换时,注意相同的单词不能交换,不能连着交换一个单词两次(例a, b, c不能交换成b,c,a)
其中dp[i]为前 i 个单词组成的“几乎相等”字符串的个数,所以dp[0]=dp[1]=1;
相邻两个单词相等,则不交换为dp[i]=dp[i-1];
不等交换,为dp[i]=(dp[i-1]+dp[i-2])%mod;
代码:
#include<bits/stdc++.h> using namespace std; const int N = 100005, mod = 1e9 + 7; int f[N], n; string s[N]; int solve() { cin >> n; for (int i = 1; i <= n; i ++) { cin >> s[i]; } fill(f, f + n + 1, 0); f[0] = 1; for (int i = 1; i <= n; i ++) { f[i] = f[i - 1]; if (i >= 2 && s[i] != s[i - 1]) { f[i] = (f[i] + f[i - 2]) % mod; } } return f[n]; } int main() { int Test; cin >> Test; for (int Case = 1; Case <= Test; Case ++) { printf("%d\n", solve()); } return 0; }
1011 Kindergarten Physics
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6812
题意:
两个小球同时下落,求他们之间的距离
思路:
一个理解题意的题,有两个重a,bkg的个,初始时候相距d距离,在只受重力影响的情况下,试问一段时间后他们之间的距离。根据初中知识,距离不变,所以我们只需要直接输出即可(这题就离谱)。
代码
#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; }