codeforces 1281C. Cut and Paste(模拟)

本文详细解析 Codeforces 1281C 题目,通过实例说明如何处理字符串操作问题,避免内存溢出,提供了一种高效算法来计算最终字符串长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C. Cut and Paste

题目链接:codeforces 1281C

题意:

    题目较长,举例说明,T组样例,X次操作,给一个只包含‘1’‘2’‘3’的字符串s,在对s进行x次操作后,问s最终长度

举例:x = 5 ,s = 231

第一次操作: 将字符串分为两个分别是 2  和 31,  然后将31复制2次(复制2次是因为第一个字符是2),放在分开的第一个字符串2后面,拼成新的字符串2 31 31(中间本身没有空格,方便观察)

第二次操作:将第一次操作得到的字符串分为两个分别是  23 和131,然后将131复制3次(复制3次是因为第二个字符是3),放在分开第一个字符串23后面,形成新的字符串23 131 131 131

第三次操作:将第二次操作得到的字符串分为两个分别是 231 和 31131131,然后将 31131131复制1次(复制1次是因为第三个字符是1),放在分开的第一个字符串231后面,形成新的字符串231 31131131

.........依次类推,

分开的两个字符串,第一个字符串长度每次递增1

 

解题思路:

     首先不能直接构造最终的字符串,会直接爆掉(超出内存),仔细分析后得出:只需构造出长度最长为x的字符串即可。

  理由:得到第 i 个字符为多少即可知道后面的字符串复制了多少次,知道了字符串长度即可知道复制的字符串长度。

 

我感觉讲的差不多了,还是有问题的话,可以评论(有问题请多多指教)。

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
ll ans;
int main(){
    int t;
    cin >> t;
    while(t--){
    	int x, l = 1;
    	string s;
    	cin >> x >> s;
    	int len = s.size();
    	while(len < x){
    		for(int i = 1; i < s[l-1] - '0'; i++){
    			s += s.substr(l, len -l);     // 将分开的第二个字符串复制s[l-1]次后拼接
    		}
    		len = s.size();
    		l++;
    	}
    	// 此处的得到长度大于x的字符串
    	ans = s.size() % mod;
    	for(int i = l; i <= x; i++){ // 此处l指的是之前已经进行了多少次操作
    		ans = (ans + (s[i-1]-'0' - 1) * (ans - i) % mod + mod) % mod;
    		// s[i-1]-'0'指的是当前字符为几,-1是因为要少复制一次,如果是2本质上只用复制1次
    		// ans-i 是因为分开的两个字符串,第一个字符串每次递增1,那么ans-i就是需要复制的字符串长度
    	}
    	cout << ans << endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值