859.亲密字符串
题目大意:给出两个字符串A和B,是否可以交换A中两个字母得到B
题解:这是一道细节颇多的easy题,第一步判断长度,第二步判断每个字母的个数,第三步判断有多少个位置不相等,2个的话就返回true,0个的话,还要判断是否有出现两次的字母
class Solution {
public:
bool buddyStrings(string A, string B) {
int len=A.length();
int len2=B.length();
int cnt[30]={0}, cnt2[30]={0};
if (len!=len2) return false;
for(int i=0; i<len; i++) {
cnt[A[i]-'a']++;
cnt2[B[i]-'a']++;
}
int ok=0;
for(int i=0; i<26; i++) {
if (cnt[i]>=2) ok=1;
if (cnt[i]!=cnt2[i]) return false;
}
int pos=-1, pos2=-1;
for(int i=0; i<len; i++) {
if (A[i]==B[i]) continue;
if (pos==-1) pos=i;
else if (pos2==-1) pos2=i;
else return false;
}
if (pos==-1) return ok;
if (pos2==-1) return false;
swap(A[pos], A[pos2]);
return A==B;
}
};
856.括号的分数
题目大意:给出一个括号表达式,计算括号的分数,并给出分数的计算方式
题解:括号表达式可以建成一棵树,叶子结点分数为1,非叶子结点分数为子节点分数之和乘2,答案就为根节点的分数/2
class Solution {
public:
vector<int> V[100];
int cnt=0;
int score[100];
int fa[100];
void dfs(int cur) {
for(int i=0; i<V[cur].size(); i++) {
int u=V[cur][i];
dfs(u);
score[cur]+=score[u];
}
if (V[cur].size()==0) score[cur]=1;
else score[cur]*=2;
}
int scoreOfParentheses(string S) {
int len=S.length();
int cur=0;
for(int i=0; i<len; i++) {
if (S[i]=='(') {
cnt++;
V[cur].push_back(cnt);
fa[cnt]=cur;
cur=cnt;
}
else if (S[i]==')') {
cur=fa[cur];
}
}
dfs(0);
return score[0]/2;
}
};
858.镜面反射
题目大意:从左下角射出一道光,在一个正方形内镜面反射,问先到达哪个角落
题解:注意到光的反射可以看作光不动,正方形镜面对称,然后再发现光到角落其实就是到了p和q的最小公倍数,比赛时一直在想拓展欧几里得,结果发现并不熟,还是太弱
class Solution {
public:
int gcd(int a, int b) {
if (!b) return a;
else return gcd(b, a%b);
}
int mirrorReflection(int p, int q) {
int lcm=p*q/gcd(p, q);
int s=lcm/p;
cout<<s<<endl;
int t=lcm/q;
cout<<t<<endl;
swap(t, s);
if (s%2==1&&t%2==0) return 0;
if (s%2==1&&t%2==1) return 1;
if (s%2==0&&t%2==1) return 2;
}
};
857.雇佣K名工人的最低成本
题目大意:题意还挺绕的,简单来说要满足每个人的工资要大于最低工资和大于总工资*系数,这个系数为其工作质量除以总工作质量
题解:
wage[i]≤sum∗quality[i]∑quality[i]
w
a
g
e
[
i
]
≤
s
u
m
∗
q
u
a
l
i
t
y
[
i
]
∑
q
u
a
l
i
t
y
[
i
]
化简式子
wage[i]∗∑quality[i]quality[i]≤sum
w
a
g
e
[
i
]
∗
∑
q
u
a
l
i
t
y
[
i
]
q
u
a
l
i
t
y
[
i
]
≤
s
u
m
注意到,总工资sum最强约束条件为所雇佣K名工人中左边wage/quality最大的人,这样对于K名工人的sum,所以我们不断枚举最强约束,然后令总的quality最小就好了,这样枚举过程就会产生答案了
#define pb push_back
#define mp make_pair
#define CLR(a) memset(a, 0, sizeof(a))
#define DBG(x) cout<<(#x)<<"="<<x<<endl
#define FOR(i, a, b) for(int i=(a); i<(b); i++)
#define REP(i, a, b) for(int i=(a); i<=(b); i++)
#define DOWN(i, a, b) for(int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1000000009;
struct node {
ll q;
ll w;
bool operator <(const node& rhs) const {
return w*rhs.q<rhs.w*q;
}
}p[10010];
class Solution {
public:
double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) {
int n=quality.size();
DBG(n);
REP(i, 1, n) {
p[i].q=quality[i-1];
p[i].w=wage[i-1];
}
sort(p+1, p+n+1);
ll sum=0;
priority_queue<ll> Q;
REP(i, 1, K) {
sum+=p[i].q;
Q.push(p[i].q);
}
double ans=1.0*p[K].w/p[K].q*sum;
REP(i, K+1, n) {
sum-=Q.top();Q.pop();
sum+=p[i].q;
Q.push(p[i].q);
ans=min(ans, 1.0*p[i].w/p[i].q*sum);
}
return ans;
}
};