SRM628题解 (T3除外)

T1:

题目大意:定义 d(n)为 n 的约数个数,h(n) = n ^ d(n) (n的d(n)次方),现给定 x,求 满足 h(n) = x的最小的n。


主要思路:枚举指数 i ,判断是否存在 k 使得 k ^ i == x ,再判断 k的约数个数是否为i即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

typedef long long LL;
const double esp = 1e-9;

LL power(LL a, LL b, LL n) {
    LL ans = 1;
    for (int i = 1; i <= b; ++i) {
	if (ans > n / a) return n + 1;
	ans = ans * a;
    }
    return ans;
}

int find(LL X) {
    int ans = 0;
    for (int i = 1; (LL) i * i <= X; ++i) 
	if (X % i == 0) {
	    ans++;
	    if (X / i != i) ++ans;
	}
    return ans;
}

class DivisorsPower {
public :
    LL findArgument(LL n) {
	LL ans = -1;
	for (int i = 2; i <= 63; ++i) {
	    LL A = exp(log(n) / i) + 1e-3;
	    LL C = power(A, i, n);
	    //if (i <= 3) cout<<i<<" "<<A<<" "<<C<<endl;
	    if (C != n) continue;
	    int t = find(A);
	    if (t != i) continue;
	    ans = A;
	}
	return ans;
    }
};


T2:

题目大意:给定一个字符串序列,基本元素为'X',Ac1c2代表将元素c1和c1联合起来组成新元素,权值w(Ac1c2) = w(c1) + w(c2),Bc1c2代表将元素c1和c2联合起来,权值w(Bc1c2) = max (w(c1), w(c2))。现在序列中有 n个基本元素,他们的权值分别为b[1] ... b[n],求如何安排基本元素的权值使得序列权值最大(每个基本元素选择一个bi,且每个bi只能被一个基本元素选择)。


主要思路:对于 Bc1c2,w(Bc1c2) = max(w(c1) + w(c2)),所以我们只要关心c1,c2其中一个的基本元素的权值就好了(另一个对答案不够成影响)。对于Ac1c2,w(Ac1c2) = w(c1) + w(c2),所以c1,c2中的基本元素都对答案构成影响。根据贪心,有影响的基本元素权值越大越好,假设有 t 个基本元素对答案有影响,则整个序列的权值为b数组中前t大的权值和。所以问题转化求有影响的基本元素的最大值,即求基本元素的权值都为1的序列的权值。


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

int a[10000];
int n, m;
string S;

pair<int, int> dfs(int x) {
    if (S[x] == 'X') return make_pair(1, x);
    pair<int, int> x1 = dfs(x + 1);
    pair<int, int> y1 = dfs(x1.second + 1);
    if (S[x] == 'A') return make_pair(x1.first + y1.first, y1.second);
    return make_pair(max(x1.first, y1.first), y1.second);
}

class CircuitsConstruction {
public:
    int maximizeResistance(string circuit, vector <int> conductors) {
	n = conductors.size();
	S = circuit;
	m = S.size();
	sort(conductors.begin(), conductors.end());
	for (int i = 0; i < n; ++i)
	    a[i] = conductors[i];
	for (int i = 0 , j = n - 1; i < j; ++i, --j)
	    swap(a[i], a[j]);
	int p = dfs(0).first;
	int ans = 0;
	for (int i = 0; i < p; ++i) ans += a[i];
	return ans;
    }
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值