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) ((x1)/m,(x1)%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;
}
posted @   unique_pursuit  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示