232.66+368.81+685.73=1287.2
T2花的时间有点久,T1也没上240…
不过难得A了还是很开心的~~
题解要不就坑着叭QAQ
反正也不会被钦定到
反正也没什么事干我来填坑了
T1 LengthUnitCalculator
就是个单位换算,模拟一波就行。
#include <bits/stdc++.h>
using namespace std;
const string a[4]={"mi","yd","ft","in"};
const int b[3]={1760,3,12};
class LengthUnitCalculator {
public:
double calc( int amount, string fromUnit, string toUnit );
};
double LengthUnitCalculator::calc(int amount, string fromUnit, string toUnit) {
int x,y;
for(int i=0;i<4;i++) if (a[i]==fromUnit) x=i;
for(int i=0;i<4;i++) if (a[i]==toUnit) y=i;
if (x==y) return (double)amount;
if (x<y){
for(int i=x;i<y;i++)
amount*=b[i];
return (double)amount;
}
cout<<x<<' '<<y;
double ans=amount;
for(int i=x-1;i>=y;i--)
ans/=(double)b[i];
return ans;
}
T2 ShortestPathWithMagic
你有 瓶魔法药水,每次可以将一条路的长度减半,一条路最多只能用一瓶药水,不一定要用所有药水。求0到1的最短路。
用 表示到 点时用了 瓶药水的最短路,跑最短路就行。博主懒,直接上没堆优化的 了。
不过我的代码里 是实际值的两倍,这样就没小数。
#include <bits/stdc++.h>
using namespace std;
const int N=55;
int n;
int f[N][N],b[N][N];
class ShortestPathWithMagic {
public:
double getTime( vector <string> dist, int k );
};
double ShortestPathWithMagic::getTime(vector <string> dist, int k) {
n=dist.size();
memset(f,0x3f,sizeof f);
for(int i=0;i<=k;i++) f[0][i]=0;
for(int o=1;o<=n*(k+1);o++){
int x=n,y=k+1;
for(int i=0;i<n;i++)
for(int j=0;j<=k;j++)
if (f[i][j]<f[x][y]&&!b[i][j]){
x=i;y=j;
}
b[x][y]=1;
for(int i=0;i<n;i++)
{
f[i][y]=min(f[i][y],f[x][y]+2*(dist[x][i]-'0'));
f[i][y+1]=min(f[i][y+1],f[x][y]+dist[x][i]-'0');
}
}
int ans=2e9;
for(int i=0;i<=k;i++) ans=min(ans,f[1][i]);
cout<<ans;
return (double)ans/2.0;
}
T3 TreeAndPathLength2
问是否存在 个点,长度为 的简单路径有 条的树。
对于点 ,假设它的度数为 ,很明显以i为中心的长度为 的简单路径的条数为
由于是一棵树,共有 条边,所以所有点的度数加起来是 。
并且,对于任意总度数为 的连通图,它必然是一棵树。
那么题目就是求 且 的树是否存在。
考虑DP。
用 表示 且 的方案是否存在,然后枚举下一个点的度数,就可以转移了,注意必须 ,因为树是联通的。
这个复杂度看起来非常玄学,但是仔细想一下感觉还是非常有道理的。
#include <bits/stdc++.h>
using namespace std;
int f[51][101][1001];
class TreeAndPathLength2 {
public:
string possible( int n, int s );
};
string TreeAndPathLength2::possible(int n, int s) {
f[0][0][0]=1;
int m=(n-1)<<1;int w;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
for(int k=0;k<s;k++)
if (f[i][j][k])
for(int l=1;j+l<=m;l++){
w=l*(l-1)>>1;
if (k+w>s) break;
f[i+1][j+l][k+w]=1;
}
if (f[n][m][s]) return "Possible";
else return "Impossible";
}