AcWing第126周周赛题解

AcWing126周周赛题解:

第一题:

蜗牛在 n米深的井底往上爬,每天清晨到傍晚向上爬 5米,夜间又滑下来 4米,请问像这样从某天清晨开始,第几天爬到井口?

输入格式
一个正整数 n。

输出格式
一个整数,表示爬到井口的天数。

数据范围
前 3个测试点满足 1≤n≤100。
所有测试点满足 1≤n≤10000。

输入样例:

10

输出样例:

6

Ans:貌似记得是蓝桥杯的真题吧1.模拟,在日出时长度+5,如超过深度则输出该天数,否则长度-4。2.找规律:如果深度大于5则出输出深度-5+1,否则输出1

#ANS1
#include<iostream>

using namespace std;

int main(){
    int n;
    cin >> n;
    
    int tot = 0;
    int ans = 1;
    while(true){
        tot = tot+5;
        if(tot >= n){
            cout << ans << endl;
            break;
        }
        else{
            tot = tot - 4;
            ans++;
        } 
    }

    return 0;
    
}
#include<iostream>

using namespace std;

int main(){
    int n;
    cin >> n;
    
    if(n>5) cout << n-5+1;
    else cout << "1";

    return 0;
    
}

第二题:

给定一个长度为 n的字符串 s和一个长度为 m 的字符串 t。
字符串 s 和 t均由小写字母组成,字符串 s的长度不超过字符串 t的长度。

我们希望字符串 s成为字符串 t的子串。

为此,你可以进行任意次(也可以不进行)字符替换操作。
每次操作可以任选字符串 s中的一个字符并将其替换为 ?。? 可以视为等于任何其它字符。

请你计算,为了使得字符串 s成为字符串 t的子串,所需进行的最少操作次数,并提供一种具体操作方案。

例如,如果 s为 abd,t为 abcd,那么我们可以进行一次操作,将 s中的第 3个字符替换为 ?,替换后 s变为 ab?,可以与字符串 t的子串 abc 匹配。

输入格式
第一行包含两个整数 n,m。
第二行包含一个长度为 n的由小写字母构成的字符串 s。
第三行包含一个长度为 m的由小写字母构成的字符串 t。

输出格式
首先,输出一行,一个整数 k,表示所需的最少操作次数。

如果 k=0,则输出到此为止,不要输出多余空行。

如果 k≠0,则还需再输出一行 k个整数,其中第 i个整数表示第 i个操作所替换字符的位置编号。

s中字符的位置从左到右依次编号为 1∼n。

如果方案不唯一,输出任意合理方案均可。

数据范围
前 6个测试点满足 1≤n≤m≤10。
所有测试点满足 1≤n≤m≤1000。

输入样例1:

3 5
abc
daebf

输出样例1:

2
2 3

输入样例2:

4 10
abcd
fbcfabaecd

输出样例2:

1
2

Ans:1.模拟,直接从父串每一个index开始依次和子串进行比对,记录最大的相似度,和不同的字符坐标。2.对子串进行切片,然后直接在父串中去.find观察是否存在切片后的子串,记录切片子串的最大长度。

#include<iostream>
#include<vector>

using namespace std;

int n,m;
char t[1010];
char s[1010];

int main(){
    cin >> n >> m;
    for(int i = 1;i <= n;++i) cin >> t[i];
    for(int j = 1;j <= m;++j) cin >> s[j];
    int max = 0;
    vector<int>index;
    vector<int>::iterator it;
    vector<int>ans;
    for(int i = 1;i+n <= m+1;++i){
        int p = 0;
        index.clear();
        for(int j = 1;j <= n;++j){
           if(t[j] == s[j+i-1]) p++;
           else index.push_back(j);
        }

        if(p >= max){
            ans = index;
            max = p; 
        }
    }

    cout << n-max << endl;
    for(it=ans.begin();it!=ans.end();++it) cout << *it << ' ';

    return 0;
    

}

第三题

某字符串序列 s0,s1,s2,…的生成规律如下:

s0=

DKER EPH VOS GOLNJ ER RKH HNG OI RKH UOPMGB CPH VOSFSQVB DLMM VOS QETH SQB

sn=

DKER EPH VOS GOLNJ UKLMH QHNGLNJ A+sn−1+
AB CPH VOS FSQVB DLMM VOS QHNG A+sn−1+
AB

其中 n≥1。
你需要回答 q个询问,其中第 i个询问给定两个整数 n,k并请你输出字符串 sn中的第 k个字符(字符串中的字符索引编号从 1开始,如果 sn的长度小于 k,则输出 ’ . ’

输入格式
第一行包含整数 q。
接下来 q行,每行包含两个整数 n,k,表示一个询问。

输出格式
共一行,一个长度为 q 的字符串,其中第 i个字符表示第 i个询问的答案。
保证答案的首尾字符不是空格。

数据范围
前 3个测试点满足 0≤n≤5。
所有测试点满足 1≤q≤10,0≤n≤105,1≤k≤1018

输入样例1:

3
1 1
1 2
1 1000000000000000000

输出样例1:

DK.

输入样例2:

5
0 69
1 194
1 139
0 47
1 66

输出样例2:

EFGHI

Ans:其实并不难,根据sn的递推公式去递归过程得到答案(k的值需要去long long)

#include<iostream>
#include<vector>

using namespace std;

typedef long long ll;
const int N = 1e5+5;
const long long INF = 2e18;
ll slen[N];

string s0 = "DKER EPH VOS GOLNJ ER RKH HNG OI RKH UOPMGB CPH VOS FSQVB DLMM VOS QETH SQB";
string add1 = "DKER EPH VOS GOLNJ UKLMH QHNGLNJ A";
string add2 = "AB CPH VOS FSQVB DLMM VOS QHNG A";
string add3 = "AB";

int len1 = add1.size();
int len2 = add2.size();
int len3 = add3.size();

char get(int n,ll k){
     if(k > slen[n]) return '.';
     if(n == 0) return s0[k-1];
     if(k <= len1) return add1[k-1];
     if(k > len1 && k <= len1 + slen[n - 1])
        return get(n - 1, k - len1);
     if(k > len1 + slen[n - 1] && k <= len1 + slen[n - 1] + len2)
        return add2[k - len1 - slen[n - 1] - 1];
    if(k > len1 + slen[n - 1] + len2 && k <= len1 + 2 * slen[n - 1] + len2)
        return get(n - 1, k - len1 - len2 - slen[n - 1]);
    return add3[k - len1 - len2 - 2 * slen[n - 1] - 1];
}

int main(){
    slen[0] = s0.size();
    for(int i = 1; i <= 1e5; i++) {
        if(slen[i - 1] >= 1e18) {
            slen[i] = INF;
            continue;
        }
        slen[i] = len1 + 2 * slen[i - 1] + len2 + 2;
    }
    vector<char>ans;
    vector<char>::iterator it;
    int n;
    cin >> n;
    while(n--){
        int temp1;
        ll temp2;
        cin >> temp1 >> temp2;
        ans.push_back(get(temp1,temp2));
    }
    

    for(it = ans.begin();it != ans.end(); ++it){
        cout << *it;
    }

    return 0;
}

END

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值