Codeforces Round #710 (Div. 3) A~E题解
文章目录
题目链接
A. Strange Table(思维)
-
解题思路
我们可以直接根据坐标来处理,对于按列来排的,其实就可以看成一个 m × n m\times n m×n的矩阵往左旋转 90 90 90度,为了计算方便,我们需从下标 0 0 0开始编号(这不会有影响,最后求得的编号 + 1 +1 +1即可)。那么我们易知,其坐标就为 ( ( x − 1 ) / m , ( x − 1 ) % m ) ((x-1)/m,(x-1)\%m) ((x−1)/m,(x−1)%m),那么这个横纵坐标互换即可得到我们按行排列的坐标,利用横坐标 × \times ×列数 + + +列坐标 + 1 +1 +1即是最后得到的答案。(不要忘记加回 1 1 1)。 -
AC代码
/**
*@filename:A
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-25 22:34
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
ll t,n,m,x;
void solve(){
x--;
ll temp1=x/n,temp2=x%n;
cout<<temp2*m+temp1+1<<endl;
}
int main() {
while(cin>>t){
while(t--){
cin>>n>>m>>x;
solve();
}
}
return 0;
}
B.Partial Replacement(贪心)
-
解题思路
这道题就是纯贪心题目,我们首先需要找到前后'*'
的位置(如果只有一个,即前后位置相同,那么直接就可以输出。),那么在之后我们就可以开始贪心了,我们最多能跨度 k k k,且题目保证两个'*'
的位置最多不会超过 k k k,所以我们可以找满足跨度小于等于 k k k的跨度最远的位置,那么这样我们能保证转换的次数是最少的。在这个贪心过程下,我们需要不断更新左端点,直到这左端点和尾部的距离是满足条件的。 -
AC代码
/**
*@filename:B
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-25 22:49
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
int t,n,k;
int ans;
string s;
void solve(){
int left=0,right=n-1;
while(s[left]!='*')left++;
while(s[right]!='*')right--;
if(left==right){
cout<<1<<endl;
return;
}
ans=2;
while(right-left>k){
//开始枚举,我们选一个跨度从高到底开始。
for(int i=left+k;i>left;i--){
if(s[i]=='*'){
ans++;
left=i;
break;
}
}
}
cout<<ans<<endl;
}
int main() {
while(cin>>t){
while(t--){
cin>>n>>k;
cin>>s;
solve();
}
}
return 0;
}
C.Double-ended Strings(字符串+暴力枚举)
-
解题思路
由于数据量不大,所以我们可以直接枚举它们相等的子串,当然,我们要取最优值,即找到满足条件的最长子串。值得注意的是,我们必须判断它们的子串是否为空串,这个判断我们可以根据 a n s ans ans的值是否改变可得知。 -
AC代码
/**
*@filename:C
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-25 23:48
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
int t;
int ans;
string a,b;
void solve(){
//枚举a的子串。空字符串也相等。
ans=1000000;
int len_a=a.size(),len_b=b.size();
for(int i=0;i<len_a;i++){
for(int j=1;i+j<=len_a;j++){
string temp=a.substr(i,j);
if(b.find(temp)!=string::npos){
ans=min(ans,len_b+len_a-2*j);
}
}
}
if(ans==1000000){
cout<<len_a+len_b<<endl;
}
else{
cout<<ans<<endl;
}
}
int main() {
while(cin>>t){
while(t--){
cin>>a>>b;
solve();
}
}
return 0;
}
D. Epic Transformation(思维)
-
解题思路
这个题其实难度并不大,想到了就立马可以写出来,我们来分析一下。题目意思是我们可以选取两个不相等的数字进行移除。那么我们总会想到先将重复数量最多的数字给移除(按照最优来想),也就是起决定性因素的是数量最多的那个数,而倘若最多的那个比剩余的数数量还多,那么我们很容易就知道最后剩的数为最多的减去抵消的。若小于,则我们发现,不管怎样,我们内部都可以进行抵消,因为我们总能进行两两消去,那么剩余的也就只和n的奇偶性有关了。 所以这道题我们处理可以用 m a p map map存储数字的数量,最后判断出现次数最多的与 n n n的关系,就可轻易得出了。 -
AC代码
/**
*@filename:D
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-26 00:07
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;
int t,n;
map<int,int> p;
void solve(){
vector<int> cnt;
for(auto &x:p){
cnt.emplace_back(x.second);
}
//我们知道,不相同的是可以相互抵消的,
//倘若最多的那个比剩余的数还多,那么我们很容易就知道最后剩的数为最多的减去抵消的。
//若小于,则我们发现,不管怎样,我们内部都可以进行抵消,因为我们总能找到最优的抵消,那么剩余的也就只和n的奇偶性有关了。
sort(cnt.begin(),cnt.end());
if(cnt.back()*2>n){
cout<<cnt.back()*2-n<<endl;
}
else{
cout<<n%2<<endl;
}
}
int main() {
while(cin>>t){
while(t--){
cin>>n;
p.clear();
int temp;
for(int i=0;i<n;i++){
cin>>temp;
p[temp]++;
}
solve();
}
}
return 0;
}
E. Restoring the Permutation(构造+思维)
-
解题思路
我们首先要知道最大值更新的关系,倘若随着下标的递增,最大值发生了改变,那么说明此时下标对应的值就为最大值。 根据这个我们可以唯一确定该位置上的数。那么如果最大值没有发生改变呢?那么我们就知道这个值就必须是比最大值还要小的且未出现过的数。 为什么要知道这个呢?这就为我们接下来的构造打下基础,题目要求我们找到字典序最小和字典序最大的数组,而我们也知道,对于最大值发生更新的点,这些都是确定了的,所以我们要填充其他的未确定的位置的值,由于我们可以知道未确定的值的取值,那么我们总能想到,若字典序最小,则在高位填入所能填的最小值,若是字典序最大,则在高位填入所能填的最大值,那么利用这个特性,我们可以用队列和栈来存储所能填的值,采用它们其实利用它们的特性,因为我们存储可填值的时候是从小到大的,那么栈可以获取可填值得最小值,而队列可以获取可填值得最大值。这正好符合我们的要求,所以我们需要做的就是判断最大值是否发生改变,同时我们也要时刻更新可填值的最小值。具体看AC代码。 -
AC代码
/**
*@filename:E
*@author: pursuit
*@CSDNBlog:unique_pursuit
*@email: 2825841950@qq.com
*@created: 2021-03-26 01:09
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 200000 + 5;
const int mod = 1e9+7;
int t,n;
void solve(vector<int> &a){
queue<int> q;//先进先出,存储待用的数字,构造字典序小的。
stack<int> s;//先进后厨,存储待用的数字,构造字典序大的。
vector<int> minn,maxx;
int low=1;//该变量表示当前可用数字的最小值。
for(int i=1;i<=n;i++){
//开始遍历根据最大值确定。
if(a[i-1]!=a[i]){
//说明该位置的数会比之前的大,则该位置的数就为最大值,同样,之间的数都可以功供我们枚举。
for(int j=low;j<a[i];j++){
s.push(j),q.push(j);
}
//这样这些数都被用光了,我们需要更改low的值。
low=a[i]+1;
minn.push_back(a[i]);
maxx.push_back(a[i]);
}
else{
minn.push_back(q.front()),q.pop();
maxx.push_back(s.top()),s.pop();
}
}
for(int i=0;i<minn.size();i++){
cout<<minn[i];
i==minn.size()-1?cout<<endl:cout<<" ";
}
for(int i=0;i<maxx.size();i++){
cout<<maxx[i];
i==maxx.size()-1?cout<<endl:cout<<" ";
}
}
int main() {
while(cin>>t){
while(t--){
cin>>n;
vector<int> a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
}
solve(a);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)