Codeforces 1281 C

2 篇文章 0 订阅

Codeforces 1281 C
题目大致解释
T组样例,X次操作,给一个只包含‘1’‘2’‘3’的字符串s,在对s进行x次操作后,问s最终长度。

(模拟题)

举例:
s=123abc ; x=5

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

第一次操作: 将字符串分为两个分别是 2 和 31, 然后将31复制2次(复制2次是因为第一个字符是2),放在分开的第一个字符串2后面,拼成新的字符串2 31 31

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

第三次操作:将第二次操作得到的字符串分为两个分别是 231 和 31131131,然后将 31131131复制1次(同上),形成新的字符串231 31131131(复制一次还是其本身)

思路:不能直接构造最后形成得字符串,,会容易超出内存,所以只需构造长度最长为x得字符串。当得到第i个字符是多少时,就可以知道后面字符中复制了几次,知道了字符串长度就可以知道复制的字符串长度。

#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
#define pi 3.141592653589793
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+100;
int main() {
	int t;
	ll m=0;
	cin >> t;
	while(t--) {
		int x, l=1;
		string s;
		cin >> x>> s;
		int len = s.length();
		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的字符串
		 m= s.size() % mod;
		for(int i = l; i <= x; i++) { //l指的是前面已经进行得操作数 
			m = (m + (s[i-1]-'0' - 1) * (m - i) % mod + mod) % mod;		
		}
		// s[i-1]-'0'判断当前字符是多少,-1是指要少复制一次,例如当是2时实际上只用复制1次,是1时就是不进行复制,即其本身 
		// m-i 是因为要对字符串进行分割后再复制,分割后的第一个字符串每次递增1,那么m-i就是需要复制的字符串长度
		cout << m << endl;
	}
	return 0;
}

拓展

substr函数
substr(pos,n)
返回一个string,包含s中从pos开始的几个字符的拷贝
其中pos默认值为0,n的默认值为s.size()-pos。

举例:s=123abc

  1. 不加参数会拷贝整个s。 s.substr()返回123abc

  2. 只有pos,从pos开始拷贝剩下的全部字符。 s.substr() 返回abc。

  3. 当pos超过字符串长度,会出现out_of_range的异常。
    在这里插入图片描述

  4. 当pos+n超过时,则substr会调整n的值,只拷贝到string的末尾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值