文章目录
前言
蒟蒻又来发题解了,今天也是来补题的一天 QWQ
A. Strange Table
题目的大致意思:原来有n行m列的数字,现在指定一个数字,记住它现在的位置。将这些数字改为m行n列排列,原来指定数字所在位置现在的数字是多少。
解题思路:先记录指定数字的行,列,改变排列方式之后无非是把一行有的数字个数和一列有的数字个数互换了。用行数减1乘现在一行的数字个数(相当于求完整行数所有的数字),然后加上列数就是现在位置上面的数字了。
题解:
#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
int t;
cin>>t;
while(t--){
ll n,m,x;
cin>>n>>m>>x;
ll row=x%n;//储存行数
ll ans=x/n+(x%n!=0);//原来的列数
if(row==0)row=n;
ans+=(row-1)*m;//求现在的数字了
cout<<ans<<endl;
}
return 0;
}
B. Partial Replacement
题目的大致意思:给定字符串由’.‘和’*'组成,由一下三个操作:
1.将第一个 *改为X;
2.将最后一个 *改为X;
3.将中间的 *改为X,并保证两个相邻的X之间的间隔不能大于k
输出替换 *的最小操作次数。
解题思路:第一遍遍历字符串将所有 * 的索引由vector容器储存,然后遍历容器内相邻两个索引的值,如果两个索引相差大于k,就必须将前面q对应位置的*改为X,缩短两个X之间的间隔。
题解:
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
int main()
{
int t;
cin>>t;
while(t--){
int n,k;
string s;
vector<int>v;
cin>>n>>k>>s;
for(int i=0;i<n;i++){
if(s[i]=='*')
v.push_back(i);
}
if(v.size()<=2)cout<<v.size()<<endl;
else{
int ans=1;
for(int i=0;i<v.size()-1;i++){
int j=i+1;
while(j<v.size()&&v[j]-v[i]<=k)j++;
j--;
ans++;
i=j-1;
}
cout<<ans<<endl;
}
}
return 0;
}
C. Double-ended Strings
题目的大致意思:给定a,b两个字符串,将a,b头尾字母进行删除处理,直到最后两字符串相等,输出操作次数。
解题思路:先求俩字符串的连续相等的子字符串的长度,用俩字符串长度和减去子字符串的长度的2倍就是进行操作的次数了。
题解:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string a,b;
int t,la,lb,maxn;
int main(){
cin>>t;
while(t--){
cin>>a>>b;
maxn = 0;
la = a.length(),lb = b.length();
for(int l = 1;l <= la && l <= lb;++l){ //俩字符串的长度都小于20,用三个for循环完全可以进行
for(int i = 0;i < la - l + 1;++i){
for(int j = 0;j < lb - l + 1;++j){
bool flag = true;
for(int notea = i,noteb = j;notea <= i + l - 1;++notea,++noteb)
if(a[notea] != b[noteb]){
flag = false;break;
}
if(flag)
maxn = max(maxn,l);
}
}
}
cout<<la + lb - maxn * 2<<endl;
}
return 0;
}
D. Epic Transformation
题目的大致意思:每一次删除数组中不相等的两个数,求最后剩余的数的最少个数。
解题思路:用map储存每个数及其个数,找到数组中出现次数最多的数字,然后比较它和数组的大小,如果出现的次数达到了数组大小的1/2,那么就输出2*大小-n;否则输出n%2
题解:
#include<iostream>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
int main()
{
int t;
cin >> t;
while (t--)
{
ll n;
cin >> n;
map<ll, ll> mp;
ll mx = 0, x;
for (int i = 0; i < n; i++)
{
cin >> x;
mx = max(mx, ++mp[x]);
}
cout << max(n % 2, 2 * mx - n) << endl;
}
}
E. Restoring the Permutation
题目的大致意思:原来有1-n个数字组成了一个数组,每一个数字只出现一次,但是后来数组在袋子里面被改变了。现在给你改变后的数组要求求改变前的数组,分别求字典序最小和字典序最大的原数组。(在口袋里被改变的方法:连续的几个数字等于前面最大的那个数)
pi=max{pl,pl+1,pl+1…,pi};
解题思路:很明显这是一题不能完全用暴力解决的题,前面找到小的数字恢复原始数组可以暴力,但是后面求字典序大的就不能从后面遍历求了。但是这一题可以使用STL函数,可以明显感觉变简单了不少。好啦,直接上代码叭!
#include <iostream>
#include <set>
using namespace std;
const int N = 2e5 + 10;
int main()
{
int t;
cin >> t;
while (t--)
{
set<int> s;
int n;
cin >> n;
int x[N];
for (int i = 1; i <= n; i++)
s.insert(i);
for (int i = 1; i <= n; i++)
{
cin >> x[i];
if (x[i] != x[i - 1])
cout << x[i] << " ", s.erase(x[i]);
else
cout << *s.begin() << " ", s.erase(s.begin());
}
cout << endl;
for (int i = 1; i <= n;i++)
s.insert(i);
for (int i = 1; i <= n;i++){
if(x[i]!=x[i-1])
cout << x[i] << " ", s.erase(x[i]);
else
cout << *prev(s.lower_bound(x[i])) << " ", s.erase(*prev(s.lower_bound(x[i])));
}
cout << endl;
}
return 0;
}
总结
继续加油继续坚持!