codeforces 1281C. Cut and Paste(构造)

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章