SRM528 DIV2 解题报告

250pt:
关于回文串的题。首先对称着看,如果对称的两端都是‘?’,那么选花费较小的一种字母替换即可(关键在于费用,字符串中只要标记一下就行了),如果两端只有一个问号,那么花费是确定的,根据对称的另一端累加最小花费

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
using namespace std;

typedef long long llg;

class MinCostPalindrome{
public:
int getMinimum(string s, int oCost, int xCost){
int ans = 0, len = s.length();
for(int i = 0; i < len; i++)
if(s[i]==s[len-i-1] && s[i]=='?'){
ans += min(oCost, xCost)*2;
s[i] = s[len-i-1] = 'p';
}
for(int i = 0; i < len; i++)
if(s[i]=='?'){
if(s[len-i-1] == 'o'){
ans += oCost;
s[i] = 'o';
}
else{
ans += xCost;
s[i] = 'x';
}
}
for(int i = 0; i < len; i++)
if(s[i] != s[len-i-1])
ans = -1;
return ans;
}
};

500pt:
这题是DIV1的第一题,和250一样,也是属于被秒杀的题目。
思路:长度为10的直接拿过来就好了,然后要先切长度为20的,然后是30的。。。如果剩余没有一个长度是10的倍数了,那么随便怎么切都成= =。可以简单证明一下这种策略一定会是最优的。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include <algorithm>
using namespace std;

#define MP(x, y) make_pair((x),(y))

class Cut{
public:
bool visit[55];
int getMaximum(vector <int> p, int maxCuts){
sort(p.begin(), p.end());
int n = p.size(), ans = 0;
memset(visit, false, sizeof(visit));
for(int i = 0; i < n; i++)
if(p[i]%10 == 0){
if(maxCuts >= p[i]/10-1){
ans += p[i]/10;
maxCuts -= (p[i]/10-1);
visit[i] = true;
}
}
int tmp = 0;
for(int i = 0; i < n; i++)
if(!visit[i]){
tmp = p[i]/10;
ans += min(tmp, maxCuts);
maxCuts -= min(tmp, maxCuts);
}
return ans;
}
};

 

1000pt:

第一种想法是暴搞,爆炸范围看成一个区间,t从0开始,每次加0.01,加到1000为止。。。这么蠢的模拟方法果然过不去SystemTest的数据,我试了一下有两组数据WA。。。如果是在OI里面的话估计这种写法可以得不少分= =。摒弃侥幸心里,认真观察可以发现,无论最大解是什么,极限情况下区间两端必然是两个不同的点。我们可以枚举这两个点,假设小的那个是i,大的那个是j,那么为了求极限情况的时间t,我们可以列一个方程:xInit[j]+v[j]*t-xInit[i]-v[i]*t=2*R,那么t=(2*R-(xInit[j]-xInit[i]))*1.0/(v[j]-v[i])。由于题目保证任意两个v不会相等,所以v[j]-v[i]!=0,如果求出的t为负数,那么不处理,否则判断在时间为t的情况下,以i和j分别为左端点和右端点的区间最多包含多少只蚊子,统计一下和ans比较就可以了。

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

class Mosquitoes{
private:
const double eps;
int cmp(double x){
if(x > eps) return 1;
else if(x < -eps) return -1;
else return 0;
}
public:
Mosquitoes():eps(1e-6) {}
int getMaximum(vector <int> xInit, vector <int> v, int R){
int ans, n = xInit.size();
ans = 1;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j){
double pos, t, start, end;
t = (R*2-(xInit[j]-xInit[i]))*1.0/(v[j]-v[i]);
if(cmp(t) < 0) continue;
int ct = 2;
start = xInit[i]+v[i]*t;
end = xInit[j]+v[j]*t;
for(int k = 0; k < n; k++){
if(k!=i && k!=j){
pos = xInit[k]+v[k]*t;
if(cmp(end-pos)>=0 && cmp(pos-start)>=0)
ct++;
}
}
ans = max(ans, ct);
}
return ans;
}
};




 



你可能感兴趣的:(div)