Codeforces Round #710 (Div. 3)

A - Strange Table
思路
这个就是根据第一个矩阵来求出这个点的横坐标和纵坐标。
我当时推的就是
l = x l=x%n l=x
r = ( x − l ) / n + 1 r=(x-l)/n+1 r=(xl)/n+1
这个点x的坐标就是(l,r)。
然后根据第二个矩阵的性质求出最终结果。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll n,m,x;
        cin>>n>>m>>x;
        ll x1=x%n;
        if(x1==0) x1=n;
        ll y1=(x-x1)/n+1;

      //  cout<<x1<<" "<<y1<<endl;
        ll c=(x1-1)*m+(y1);
        cout<<c<<endl;

    }
    return 0;
}

B - Partial Replacement
思路
这就是一个模拟题,没什么好说的。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        string s;
        cin>>s;
        int flag1=0;
        for(int i=0 ; i<s.length() ; i++)
        {
            if(s[i]=='*')
            {
                flag1=i;
                break;
            }
        }
        int flag2=0;
        for(int i=s.length()-1 ; i>=0 ; i--)
        {
            if(s[i]=='*')
            {
                 flag2=i;
                 break;
            }
        }
        if(flag1==flag2)
        {
            cout<<"1"<<endl;
            continue;
        }
        int ans=0;
        s[flag1]='x';
        s[flag2]='x';
        ans+=2;
        for(int i=0 ; i<s.length() ; i++)
        {
            if(s[i]=='x')
            {
                bool flag=false;
                int c=0;
                if(i+k>=n) c=n;
                else c=i+k;
                for(int j=i+1 ; j<=c ; j++)
                {
                    if(s[j]=='x')
                    {
                        flag=true;
                        break;
                    }
                }
                if(flag) continue;
                else
                {
                    for(int j=c ; j>=i+1 ; j--)
                    {
                        if(s[j]=='*')
                        {
                            s[j]='x';
                            ans++;
                            break;
                        }
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

C - Double-ended Strings
思路
这个题就是求两个字符串的最长公共字串,昨天晚上一直WA了两发,最后才发现原来边界问题没有考虑到。

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 100;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int dp[N][N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof dp);
        string s1,s2;
        cin>>s1>>s2;
        int ans=0;
        for(int i=0 ; i<s1.length() ; i++)
        {
            for(int j=0 ; j<s2.length() ; j++)
            {
               if(s1[i]==s2[j])
               {
                   if(i==0&&j==0) dp[i][j]=1;
                   else if(i==0&&j==1) dp[i][j]=1;
                   else if(i==1&&j==0) dp[i][j]=1;
                   else
                   {
                       dp[i][j]=dp[i-1][j-1]+1;
                   }
               }
               else dp[i][j]=0;
               ans=max(ans,dp[i][j]);
            }
        }
        //cout<<ans<<endl;
        cout<<s1.length()+s2.length()-2*ans<<endl;
    }
    return 0;
}

D - Epic Transformation
思路
我看了好多大佬都是直接把每个点的次数存进来,然后就用优先队列每次拿出两个数来减一,最后输出队列中的值。
还有一些人是发现了一些性质,如果一个点的次数比其他所有点的次数都大的话,那就用这个最大次数减去其他的就是结果,如果小于的话,就判断n%2的结果,但是我到现在也不会证明。。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        map<int,int>mp;
        int n;
        cin>>n;
        int maxx=0;
        for(int i=1 ; i<=n ; i++)
        {
            int x;
            cin>>x;
            mp[x]++;
            maxx=max(maxx,mp[x]);
        }
        if(maxx>=n-maxx)
        {
            cout<<maxx*2-n<<endl;
        }
        else
        {
            if(n%2==0) cout<<"0"<<endl;
            else cout<<"1"<<endl;
        }
    }
    return 0;
}

E - Restoring the Permutation
思路
我感觉E题比D题简单,这个题只需要找到一个能支持删除和查找功能的数据结构就行,我用的是set,剩下的事情就是模拟就行了。
代码

#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int a[N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        set<int>s1,s2;
        int n;
        cin>>n;
        for(int i=1 ; i<=n ; i++) s1.insert(i);
        for(int i=1 ; i<=n ; i++) s2.insert(i);
        for(int i=1 ; i<=n ; i++) cin>>a[i];
        for(int i=1 ; i<=n ; i++)
        {
            int x=a[i];
            int j=i+1;
            while(x==a[j])
            {
                a[j]=0;
                j++;
            }
            i=j-1;
        }
    //    for(int i=1 ; i<=n ; i++) cout<<a[i]<<" ";
     //   cout<<endl;
        for(int i=1 ; i<=n ; i++)
        {
            if(a[i]!=0)
            {
                cout<<a[i]<<" ";
                s2.erase(a[i]);
            }
            if(a[i]==0)
            {
                auto it=s2.begin();
                cout<<*it<<" ";
                s2.erase(*it);
            }
        }
        cout<<endl;
        for(int i=1 ; i<=n ; i++)
        {
          //  cout<<i<<" "<<a[i]<<endl;
            if(a[i]!=0)
            {
                cout<<a[i]<<" ";
            }
            if(a[i-1]!=0&&a[i]!=0)
            {
                if(s1.find(a[i-1])!=s1.end()) s1.erase(a[i-1]);
            }
            if(a[i]==0)
            {
                auto it=s1.find(a[i-1]);
               // cout<<"a["<<i-1<<"]="<<a[i-1]<<endl;
                it--;
                cout<<*it<<" ";
                a[i]=*it;
                s1.erase(a[i-1]);
            }
        }
        cout<<endl;
    }
    return 0;
}

总结
昨天晚上被A和C题搞的有点心态蹦了,A想了好久,写出来的时候都已经过了6000人了,C题居然一直最长公共字串的DP写错了,自己的基础太不牢固了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值