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;
}


京公网安备 11010502036488号