A - 质因数分解
思路:
- 分解质因数板子
代码如下:
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define mkpr make_pair
#define x first
#define y second
#define int long long
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
const int N = 15, M = N * 2;
const int YB = 8, YM = 1e8;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int T, cases;
int n, m, times;
PII a;
void solve()
{
cin >> n;
int t;
for (int i = 2; i <= n / i; i ++ )
if(n % i == 0)
{
t = i;
break;
}
cout << n / t << endl;
return;
}
signed main()
{
T = 1;
//fast;cin >> T;
//scanf("%d", &T);
//for (cases = 1; cases <= T; cases ++ )
while(T -- )
solve();
return 0;
}
B - Prime Independence
思路:
- 严格超过我的承受范围,,不会写(望大神浇浇!)
C - Division
题意总结:
- 找到满足
p%x == 0 && q % x != 0
的,最大的x
。
思路:
- 分解质因数
具体实现:
- 若
p % q != 0
,x(max) = p
直接得到答案 - 若
p % q == 0
,证明p
和q
分解质因数得到的质因数相同,但质因数的次数不同;- 我们的目的就转化为找到集合
ok
中的最大值k
,其中集合ok
为将p
的任意的一个质因数的次数变为q
中的(此质因数的)次数-1
, - 即、使
q % ok集合中的任意值 != 0
,如此即找到答案(满足p % k == 0 && q % k != 0
的数的最大值k
)
- 我们的目的就转化为找到集合
- 考虑到对
p
分解质因数可能会 T L E TLE TLE ,我们只对q
分解质因数,并依次枚举每个质因数 - 时间复杂度为:
O
(
q
∗
l
o
g
2
(
p
)
)
O(~\sqrt{q} * log2(p)~)
O( q∗log2(p) )最大为
1e6 ~ 1e7
,可以过掉,完全没压力!
代码如下:
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define mkpr make_pair
#define x first
#define y second
#define int long long
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
const int N = 15, M = N * 2;
const int YB = 8, YM = 1e8;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int T, cases;
int n, m, times;
PII a;
void solve()
{
cin >> p >> q;
if(p % q)
{
cout << p << endl;
return;
}
int res = 0, t;
// n % x == 0 && m % x != 0
for (int i = 1; i <= q / i; i ++ )
{
if(q % i == 0)
{
if(i > 1)
{
t = p;
while(t % q == 0) t /= i;
res = max(res, t);
}
t = p;
while(t % q == 0) t /= (q / i);
res = max(res, t);
}
}
cout << res << endl;
return;
}
signed main()
{
T = 1;
fast;cin >> T;
//scanf("%d", &T);
//for (cases = 1; cases <= T; cases ++ )
while(T -- )
solve();
return 0;
}
D - Half of Same
思路:
- 暴力枚举 + 分解质因数
具体实现:
- 若可以获得相同的
n/2
个数字,则必定至少可以获得一组数量大于n/2
的a[i]
,所以得出至少n/2
的相同的数可以为a[i]
的某一个数 - 如此我们枚举每一个
v = a[i]
,对每一个大于当前相等值a[i]
的a[j]
分解质因数,找出a[j]
集合中至少在n/2 - same
个数中出现的最大数,更新最大值,从而得到结果 - 时间复杂度为:
O
(
n
2
m
a
x
(
a
[
i
]
)
)
O(n^2\sqrt{max(a[i])})
O(n2max(a[i])),最多为
1e6 ~ 2e6
,可以过。
代码如下:
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define mkpr make_pair
#define x first
#define y second
#define int long long
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
const int N = 50, M = N * 2;
const int YB = 8, YM = 1e8;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int T, cases;
int n, m, times;
map<int, int> divide_cnt;
void divide(int x)
{
for (int i = 1; i <= x / i; i ++ )
if(x % i == 0)
{
divide_cnt[i] ++;
if(x / i != i) divide_cnt[x / i] ++;
}
}
void solve()
{
cin >> n;
int a[N];
for (int i = 0; i < n; i ++ )
cin >> a[i];
int res = 0;
for (int i = 0; i < n; i ++ )
{
divide_cnt.clear();
int v = a[i];
int same = 0;
vector<int> d;
for (int j = 0; j < n; j ++ )
if(a[j] == v) same ++;
else if(a[j] > v) d.push_back(a[j] - v);
if(same >= n / 2)
{
cout << -1 << endl;
return;
}
for (auto it : d)
divide(it);
for (auto it : divide_cnt)
if(it.y >= n / 2 - same)
res = max(res, it.x);
}
cout << res << endl;
return;
}
signed main()
{
T = 1;
fast;cin >> T;
//scanf("%d", &T);
//for (cases = 1; cases <= T; cases ++ )
while(T -- )
solve();
return 0;
}
E - 分解因数
思路:
- 递归 + 分解质因数
具体实现:
divide
函数为对整数x
进行因数分解,分解出的因数大于等于st
的方案数,如此递归求解即可- 递归边界为:
x == 1
,此时返回1
代码如下:
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define mkpr make_pair
#define x first
#define y second
#define int long long
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
const int N = 50, M = N * 2;
const int YB = 8, YM = 1e8;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int T, cases;
int n, m, times;
map<int, int> divide_cnt;
int divide(int x, int st)
{
if(x == 1) return 1;
int res = 0;
for (int i = st; i <= x; i ++ )
if(x % i == 0) res += divide(x / i, i);
return res;
}
void solve()
{
cin >> n;
cout << divide(n, 2) << endl;
return;
}
signed main()
{
T = 1;
fast;cin >> T;
//scanf("%d", &T);
//for (cases = 1; cases <= T; cases ++ )
while(T -- )
solve();
return 0;
}