1、最小操作次数
两个正整数ab,删除多少次可以让a/b或者b/a正除
思路:模拟依次删除,用栈来复现。同时用一个set来去重。
#include <iostream>
#include <string>
#include <queue>
#include <set>
using namespace std;
long getMinDeleteTime(long long a, long long b) {
if (a<b) {
swap(a, b);
}
string s1 = to_string(a);
string s2 = to_string(b);
long sum = s1.size() + s2.size();
queue<pair<long long, long long>> q;
set<pair<long long, long long>> st;
q.push({a, b});
st.insert({a,b});
while(!q.empty()) {
auto p = q.front();
q.pop();
string str1 = to_string(p.first);
string str2 = to_string(p.second);
if (p.first % p.second == 0) {
return sum - str1.size() - str2.size();
}
if (str1.size() > 1) {
for (int i=0; i<str1.size(); i++) {
string tmp = str1;
tmp.erase(i,1);
long long tmp1 = atoll(tmp.c_str());
long long tmp2 = p.second;
if (tmp2 >tmp1) {
swap(tmp1, tmp2);
}
if (st.find({tmp1, tmp2}) == st.end()) {
cout << tmp1 << "," <<tmp2 << endl;
st.insert({tmp1, tmp2});
q.push({tmp1, tmp2});
}
}
}
if (str2.size() > 1) {
for (int i=0; i<str2.size(); i++) {
string tmp = str2;
tmp.erase(i,1);
long long tmp1 = atoll(tmp.c_str());
long long tmp2 = p.first;
if (tmp2 >tmp1) {
swap(tmp1, tmp2);
}
if (st.find({tmp1, tmp2}) == st.end()) {
cout << tmp1 << ","<<tmp2 << endl;
st.insert({tmp1, tmp2});
q.push({tmp1, tmp2});
}
}
}
}
return -1;
}
int main() {
long long a, b;
cin >> a >> b;
cout << getMinDeleteTime(a, b) << endl;
}
2、转化长城最小操作次数
类似[1,2,1,2,1] 或者 [2,3,2,3]都是长城数组,求从数组A转化为长城数组最少的加一次数
#include <iostream>
#include <string>
#include <vector>
using namespace std;
long long minOperationTime(vector<long long> height, long long n) {
if (n == 1) {
return 0;
}
long long a=0, b=0, a_sum=0, b_sum=0;
for (int i=0; i<n; i+=2) {
a_sum++;
if (height[i] > a) {
a = height[i];
}
}
for (int i=1; i<n; i+=2) {
b_sum++;
if (height[i] > b) {
b = height[i];
}
}
long long a_operation=0, b_operation=0;
for (int i=0; i<n; i+=2) {
a_operation += (a-height[i]);
}
for (int i=1; i<n; i+=2) {
b_operation += (b-height[i]);
}
long long res = a_operation + b_operation;
if (a == b) {
res += min(a_sum, b_sum);
}
return res;
}
int main() {
long long n;
cin >> n;
vector<long long> height(n,0);
for (int i=0; i<n; i++) {
cin >> height[i];
}
cout << minOperationTime(height, n) << endl;
}
3、red字符串
4、寻找三元组
a1,a2,......,an,求满足1<=i <j < k<<n 且 ai=ak ai>aj的数量
思路:用flag去存储,减少重复次数,还是90%
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int suitNumbers(int n, vector<long long> number) {
vector<bool> flag(n, false);
int res = 0;
for (int i=0; i<n; i++) {
if (flag[i]) {
continue;
}
flag[i] = true;
int min_number = 0;
int same_number = 1;
int total = 0;
int before = i;
for (int j=i+1; j<n; j++) {
if (number[j] < number[i]) {
min_number++;
} else if (number[j] == number[i]){
total += min_number*same_number;
res+=total;
min_number = 0;
same_number++;
before = j;
flag[j] = true;
}
}
}
return res;
}
int main() {
int n;
cin >> n;
vector<long long> number(n,0);
for (int i=0; i<n; i++) {
cin >> number[i];
}
cout << suitNumbers(n, number) << endl;
}