zoukankan      html  css  js  c++  java
  • Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3)

    题目链接:https://codeforces.com/contest/1029

    A题题解

    概述

        给定子字符串,构造包含k个该子字符串的最短字符串。

    思路

        作为div 3的第一道题自然相当随意,数据量极小,O(k*n^3)也能过的样子,可以说有思路就没有问题,事实上我也看到有大佬迭代遍历AC这道题。

        不过当我初步推理这道题时,我马上联想到KMP算法。直觉告诉我这就是这道题的最优解法,而且可以利用现成代码。接下来我就讲一讲这道题关于KMP的解法~

        还不理解KMP算法的话...出门左转见度娘~

        首先想到,最傻的方法就是把k个t串起来,必然保证有k个t;

        如何使字符串长度更短?

        假设有某种办法,那么随着总长度缩短,必然造成相邻的子字符串相互重叠,但不会完全重合或存在包含关系。换句话说,我们只需要使子字符串之间重合部分最长,就得到了最短的目标字符串。

        而每个子字符串是相等的,也就是求子字符串自己头和尾的最长重合部分。

        例如子字符串t="abcab",“ab”就是t的最长重合部分。比如k=2时,s="abcabcab"。

        讲到这里熟悉KMP的朋友们就会发现,这正是KMP实现的核心思想,KMP初始化fail/next数组就保存着这样的信息。于是我们借用KMP的初始化函数,顿时这道题只剩下简单的处理。

        注意重合部分不能是子字符串本身,例如t="aaa"时最多只能重合"aa"。

    #include<bitsstdc++.h> 
    using namespace std; 
     
    string r,s;
    int fail[100]{0};
    void make_fail(){
        for(int i=1,j=0;s[i];i++){
            while(j && s[i]!=s[j]) j=fail[j-1];
            if(s[i]==s[j])fail[i]=++j;
            else fail[i]=0;
        }
    }
     
    int main(){
        int n,k;
        cin>>n>>k;
        cin>>s;
        make_fail();
        int p=n-fail[n-1];
        if(p==0) p=1;
        for(int i=0;i<k-1;i++)
            r.append(s.substr(0,p));
        r.append(s);
        cout<<r;
        return 0;
    }
    View Code

    运用substr来做

    #include<stdio.h>
    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        int n,k;
        cin >> n >> k;
        string s;
        cin >> s;
        int temp;
    for(int i = 0; i < n ; i++) if(s.substr(0,i) == s.substr(n-i,i))  temp = i;
    for(int i = 0 ; i < k-1 ; i++) cout << s.substr(0,n-temp);
    cout << s << endl;
    return 0;
        
    }
    View Code

    B题题解

    https://blog.csdn.net/intmainhhh/article/details/82286299

    #include<stdio.h>
    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    int a[200000+10];
    int main(){
    int n;
    cin >> n;
    int x = ~1+1;
    //cout << x << endl;
    int sum = 1;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(i > 0){
            if(a[i] <= a[i-1] * 2)
            sum++;
        
        else {
            x = max(sum,x);
            sum = 1;
        }
    }
    //    cout <<sum << endl;
    }
    //if(x==0)
    //cout << "1" << endl;
    //else
    x = max(sum,x); 
    cout << x << endl;
    return 0;
    View Code

    C题题解

    multiset弄一下;

    https://www.cnblogs.com/Agnel-Cynthia/p/10604317.html

    #include<bits/stdc++.h>
    using namespace std;
    int l[300005], r[300005];
    multiset<int> a, b;
    int main(){
        int n;
        cin >> n;
        for(int i = 0 ; i < n ; i++){
            cin >> l[i];
            cin >> r[i];
            a.insert(l[i]);
            b.insert(r[i]);
        }
        int ans = ~1 + 1 + 1;
        for(int i = 0 ; i < n; i ++){
            a.erase(a.find(l[i]));
            b.erase(b.find(r[i]));
            ans = max(ans,*b.begin() - *a.rbegin());
            a.insert(l[i]);
            b.insert(r[i]);
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    D题待补

    E题待补

    F题题解

    数学题,就是已知两个颜色矩形的面积,要求最小周长,且满足其中一种颜色的为矩形

    思路:面积相同,长越大周长越小。暴力遍历。

    优化:

    1.将宽从大到小遍历,如果满足,必然最小,直接输出

    2.判断小矩形时,从大到小判断,减少复杂度(

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a ,b ,c ,d;
    const ll inff = 0x3f3f3f3f3f3f3f3fLL; //18
    bool check(ll x , ll y){
        
        for(ll i = x ; i >= 1 ; i-- ){
            if(a % i == 0 && a / i <= y) return 1;
            if(b % i == 0 && b / i <= y) return 1;
        }
        return false ;
    }
    
    int main(){
    //ll a, b;
        cin >> a >> b;
         c = a + b;
         ll ans = inff;
         //从大往小枚举,即宽最大时,周长最小 
        for(ll i = 1ll; i * i <= c; i++){
            if(c % i == 0 ){
             d = c / i;
             if(check(i,d)){
                 ans = min(ans,2ll * (d + i));
                 //不优化反而更快 
             //    cout << ans << endl;
             //    return 0;
             }
            } 
        }
        cout << ans << endl;
    }
    View Code
  • 相关阅读:
    Fiddler 教程
    Android 利用 aapt 解析 apk 得到应用名称 包名 版本号 权限等信息
    Android获取Manifest中<meta-data>元素的值
    Android资源混淆保护实践
    Android中捕获TTextView文本中的链接点击事件方法
    Android APK 手动命令编译、打包、签名步骤
    Android签名总结
    软件概要设计模板
    整理了一份React-Native学习指南
    appium简明教程(转)
  • 原文地址:https://www.cnblogs.com/Agnel-Cynthia/p/10604967.html
Copyright © 2011-2022 走看看