题意
给定一个整数n (n <= 1e5) 表示一个只由字符r和b构成的字符串序列的长度,对于该序列的任意一个区间[i,j],当该子区间中r的个数为奇数时,则称该子区间为“满意”。要求构造一系列这样的字符串序列使得其中“满意”的子区间个数最大,输出最大区间个数,另外,这样的序列一般不唯一,题目要求按字典序输出前100个构造的序列,而且先b再r。
分析:
首先计算一下某个构造子串的最大区间个数,通过推理或先r再b的打表,都能得出“全r”是要的构造之一,所以答案就是长度为n的奇数长度区间个数,直接给出代码:
for (int i = 0; i <= n; i += 2)
{
sum += (n - i);
}
构造
标准答案:暴力深搜加思维减枝,再次不做更多赘述,其他博客基本都是。
瞪眼法:(反正我在cf上跑的比标准答案快)的——找规律:
首先非常暴力打表:n在25以前是不会超时的,n<32在电脑上基本2秒内出,那么我们就可以找规律。
找规律建议:r用.代替,如图。简直显而易见的规律。
打表n=24-31,显而易见,上半部分是一个简单的一竖加斜线,唯一的区别是字符串长度(以及斜线占据的行数),下半部分中间一束一直在中间,右侧部分是一模一样的,根据n的大小平移而已。注意奇偶的区别。其实右边的规律 也可以写出来,但很麻烦,所以简单起见,可以直接把24和25的右边部分存下来(打表),根据n的大小直接输出。
而且当n大一点的时候,可想而知图像是一竖+斜线,而且n很大时,斜线只输出到100行,完全没有下面那个“叶子”状图形的事情。
那么下面直接给出代码,我设置了n<=24时暴力打表。
参考代码打表时可以修改判断语句实现n=31时打表(31是举例,随便用啥)我的打表没有优化,其实可以n^2记录r的前缀和就好,我用的n^3,反正能过。
//1表示r,0表示b。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int bef, end_, n;
vector<string> ans;
void dfs0(string s)
{
if (ans.size() == 100) return;
if (s.length() == n)
{
int sum = 0;
for (int l = 0; l < n; l++)
{
for (int r = l; r < n; r++)
{
int cnt = 0;
for (int i = l; i <= r; i++)
{
if (s[i] == 'r') cnt++;
}
if (cnt & 1) sum++;
}
} if (sum == end_) ans.push_back(s);
return;
}
dfs0(s + 'b');
dfs0(s + 'r');
}
int a[100050];
string a24[101] = {"bbbbbbbbbbbbr", "bbbbbbbbbbbrb", "bbbbbbbbbbbrr", "bbbbbbbbbbrbr", "bbbbbbbbbbrrb", "bbbbbbbbbbrrr", "bbbbbbbbbrbrb", "bbbbbbbbbrrbb", "bbbbbbbbbrrbr", "bbbbbbbbbrrrr", "bbbbbbbbrbrbb", "bbbbbbbbrrbbb", "bbbbbbbbrrbbr", "bbbbbbbbrrbrr", "bbbbbbbbrrrrb", "bbbbbbbrbrbbb", "bbbbbbbrrbbbb", "bbbbbbbrrbbbr", "bbbbbbbrrbbrr", "bbbbbbbrrbrrb", "bbbbbbbrrrrbb", "bbbbbbrbrbbbb", "bbbbbbrrbbbbb", "bbbbbbrrbbbbr", "bbbbbbrrbbbrr", "bbbbbbrrbbrrb", "bbbbbbrrbrrbb", "bbbbbbrrrrbbb", "bbbbbrbrbbbbb", "bbbbbrrbbbbbb", "bbbbbrrbbbbbr", "bbbbbrrbbbbrr", "bbbbbrrbbbrrb", "bbbbbrrbbrrbb", "bbbbbrrbrrbbb", "bbbbbrrrrbbbb", "bbbbrbrbbbbbb", "bbbbrrbbbbbbb", "bbbbrrbbbbbbr", "bbbbrrbbbbbrr", "bbbbrrbbbbrrb", "bbbbrrbbbrrbb", "bbbbrrbbrrbbb", "bbbbrrbrrbbbb", "bbbbrrrrbbbbb", "bbbrbrbbbbbbb", "bbbrrbbbbbbbb", "bbbrrbbbbbbbr", "bbbrrbbbbbbrr", "bbbrrbbbbbrrb", "bbbrrbbbbrrbb", "bbbrrbbbrrbbb", "bbbrrbbrrbbbb", "bbbrrbrrbbbbb", "bbbrrrrbbbbbb", "bbrbrbbbbbbbb", "bbrrbbbbbbbbb", "bbrrbbbbbbbbr", "bbrrbbbbbbbrr", "bbrrbbbbbbrrb", "bbrrbbbbbrrbb", "bbrrbbbbrrbbb", "bbrrbbbrrbbbb", "bbrrbbrrbbbbb", "bbrrbrrbbbbbb", "bbrrrrbbbbbbb", "brbrbbbbbbbbb", "brrbbbbbbbbbb", "brrbbbbbbbbbr", "brrbbbbbbbbrr", "brrbbbbbbbrrb", "brrbbbbbbrrbb", "brrbbbbbrrbbb", "brrbbbbrrbbbb", "brrbbbrrbbbbb", "brrbbrrbbbbbb", "brrbrrbbbbbbb", "brrrrbbbbbbbb", "rbrbbbbbbbbbb", "rrbbbbbbbbbbb", "rrbbbbbbbbbbr", "rrbbbbbbbbbrr", "rrbbbbbbbbrrb", "rrbbbbbbbrrbb", "rrbbbbbbrrbbb", "rrbbbbbrrbbbb",};
string a25[101] = {"bbbbbbbbbbbbrb", "bbbbbbbbbbbrbr", "bbbbbbbbbbbrrr", "bbbbbbbbbbrbrb", "bbbbbbbbbbrrbr", "bbbbbbbbbbrrrr", "bbbbbbbbbrbrbb", "bbbbbbbbbrrbbr", "bbbbbbbbbrrbrr", "bbbbbbbbbrrrrb", "bbbbbbbbrbrbbb", "bbbbbbbbrrbbbr", "bbbbbbbbrrbbrr", "bbbbbbbbrrbrrb", "bbbbbbbbrrrrbb", "bbbbbbbrbrbbbb", "bbbbbbbrrbbbbr", "bbbbbbbrrbbbrr", "bbbbbbbrrbbrrb", "bbbbbbbrrbrrbb", "bbbbbbbrrrrbbb", "bbbbbbrbrbbbbb", "bbbbbbrrbbbbbr", "bbbbbbrrbbbbrr", "bbbbbbrrbbbrrb", "bbbbbbrrbbrrbb", "bbbbbbrrbrrbbb", "bbbbbbrrrrbbbb", "bbbbbrbrbbbbbb", "bbbbbrrbbbbbbr", "bbbbbrrbbbbbrr", "bbbbbrrbbbbrrb", "bbbbbrrbbbrrbb", "bbbbbrrbbrrbbb", "bbbbbrrbrrbbbb", "bbbbbrrrrbbbbb", "bbbbrbrbbbbbbb", "bbbbrrbbbbbbbr", "bbbbrrbbbbbbrr", "bbbbrrbbbbbrrb", "bbbbrrbbbbrrbb", "bbbbrrbbbrrbbb", "bbbbrrbbrrbbbb", "bbbbrrbrrbbbbb", "bbbbrrrrbbbbbb", "bbbrbrbbbbbbbb", "bbbrrbbbbbbbbr", "bbbrrbbbbbbbrr", "bbbrrbbbbbbrrb", "bbbrrbbbbbrrbb", "bbbrrbbbbrrbbb", "bbbrrbbbrrbbbb", "bbbrrbbrrbbbbb", "bbbrrbrrbbbbbb", "bbbrrrrbbbbbbb", "bbrbrbbbbbbbbb", "bbrrbbbbbbbbbr", "bbrrbbbbbbbbrr", "bbrrbbbbbbbrrb", "bbrrbbbbbbrrbb", "bbrrbbbbbrrbbb", "bbrrbbbbrrbbbb", "bbrrbbbrrbbbbb", "bbrrbbrrbbbbbb", "bbrrbrrbbbbbbb", "bbrrrrbbbbbbbb", "brbrbbbbbbbbbb", "brrbbbbbbbbbbr", "brrbbbbbbbbbrr", "brrbbbbbbbbrrb", "brrbbbbbbbrrbb", "brrbbbbbbrrbbb", "brrbbbbbrrbbbb", "brrbbbbrrbbbbb", "brrbbbrrbbbbbb", "brrbbrrbbbbbbb", "brrbrrbbbbbbbb", "brrrrbbbbbbbbb", "rbrbbbbbbbbbbb", "rrbbbbbbbbbbbr", "rrbbbbbbbbbbrr", "rrbbbbbbbbbrrb", "rrbbbbbbbbrrbb", "rrbbbbbbbrrbbb", "rrbbbbbbrrbbbb", "rrbbbbbrrbbbbb",};
void solve()
{
cin >> n;
for (int i = 0; i <= n; i += 2)
{
end_ += (n - i);
}
cout << end_ << '\n';
string s;
if (n <= 24)
{
dfs0(s);
for (auto t : ans) cout << t << '\n';
return;
}
int ans;
if (n % 2 == 0)
{
int cnt = n / 2;
a[cnt + 1] = 1;
for (int i = 1; i <= n; i++)
{
cout << ((a[i] == 0) ? 'b' : 'r');
}
cout << endl;
a[cnt + 1] = 0;
a[cnt] = 1;
int k = n + 1;
ans = 1;
for (int num = 1; num <= cnt + 1; num++)
{
a[k] = 1;
a[k + 1] = 1;
a[k + 2] = 0;
for (int i = 1; i <= n; i++)
{
cout << ((a[i] == 0) ? 'b' : 'r');
}
cout << endl;
k--;
ans++;
if (ans == 100)return;
}
a[cnt] = 0;
a[cnt - 1] = 1;
k = 0;
for (int num = 1; ; num++)
{
for (int i = 1; i <= cnt; i++)
{
cout << ((a[i] == 0) ? 'b' : 'r');
}
for(int i=1;i<=(n-26)/2;i++)cout<<'b';
cout << a24[k];
cout << endl;
k++;
ans++;
if (ans == 100)return;
}
}
else
{
int cnt = (n - 1) / 2;
a[cnt + 1] = 1;
for (int i = 1; i <= n; i++)
{
cout << ((a[i] == 0) ? 'b' : 'r');
}
cout << endl;
a[cnt + 1] = 0;
a[cnt] = 1;
int k = n;
ans = 1;
for (int num = 1; num <= cnt + 1; num++)
{
a[k] = 1;
a[k + 1] = 1;
a[k + 2] = 0;
for (int i = 1; i <= n; i++)
{
cout << ((a[i] == 0) ? 'b' : 'r');
}
cout << endl;
k--;
ans++;
if (ans == 100)return;
}
a[cnt] = 0;
a[cnt - 1] = 1;
k = 0;
for (int num = 1; ; num++)
{
for (int i = 1; i < cnt; i++)
{
cout << ((a[i] == 0) ? 'b' : 'r');
}
for(int i=1;i<=(n-25)/2;i++)cout<<'b';
cout << a25[k];
cout << endl;
k++;
ans++;
if (ans == 100)return;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
return 0;
}
ps,暴力深搜直接粘的队友的,所以编译习惯不太一样哈哈哈。
pps,虽然这个暴力粘贴很抽象,但打表代码也可以很优雅的!我是这样做滴
#include<bits/stdc++.h>
using namespace std;
void solve()
{
string s;
cout << "a25[101]={";
for (int i = 1; i <= 86; i++)
{
cin >> s;
cout << "\"";
for (int j = 11; j <= 24; j++)
{
cout << s[j];
}
cout << "\",";
}
cout << "};";
}
signed main()
{
solve();
return 0;
}
ppps,手速和瞪眼法太慢了呜呜呜,最后没有在时间结束前写出来,手抖删了一个字符没发现,对拍也没写好,浪费了很多时间,只能好在还是做出来了,因为24、25字符好多,数数数的眼抽筋了【瘫倒.jpg】