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

 

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