下午学弟说第一题第二题只拿了一点分,于是过来看看题目。
P13549 热辣滚烫 - 洛谷
https://www.luogu.com.cn/problem/P13549
判断字符串s1能否插入一个字符串变成s2,判断s1是否为s2的前缀或后缀。
int n,m;
string s1,s2,str;
bool a[N],b[N];
void solve(){
cin>>n>>m;
cin>>s1>>s2;
if(n>m){
cout<<"No\n";return;
}
memset(a,0,sizeof(a));memset(b,0,sizeof(b));
a[0]=b[n]=1;
for(int k=1;k<=n;k++){
if(!a[k-1]) break;
a[k]=(s1[k-1]==s2[k-1]);
}
for(int k=n-1;k>=0;k--){
if(b[k+1]&&(s1[k]==s2[m-n+k])){
b[k]=1;
}
}
bool flag=0;
for(int k=0;k<=n;k++){
if(a[k]&&b[k]){
flag=1;break;
}
}
if(flag) cout<<"Yes\n";
else cout<<"No\n";
} P13551 ももいろの鍵 - 洛谷
https://www.luogu.com.cn/problem/P13551
这是一道构造题。
我们先考虑特殊情况 n 为 2的幂次方-1,即 n 的二进制表达为全1如 。
在这种情况下,划分组数最大的方案是什么?
是不是每组两个数每位都相反,此时划分组数最大并且值为 。
例如 ,此时划分组为

这样划分组数最大,我们假设 m为 ,即m为最小大于n且全1的。
对于此时特殊情况 m=n。
需要满足上述构造,知道 i 则对应另一个数为 ,异或上全1则会翻转。
接下来扩展到所有情况
我们照例可以通过 n 求出全1的数 m,再循环判断即可。
如果n不是2的幂减一,必定会 0~n的尾部全部去掉,剩余前面 0~x。(与首尾相加求和一个道理,会从中间开始)
递归再次处理 0~x,直到最后所有数处理完毕。
vector<vector<int>> vt;
void check(int n) {
if (n < 0) return;
if (n == 0) {
vt.push_back({0});
return;
}
int k = log2(n);
int m = (1 << (k + 1)) - 1;
for (int i = 0; i <= (m+1)/2; i++) {
int j = m ^ i;
if (j > n || i >= j) continue;
vt.push_back({i, j});
}
int L=(n^m)-1;
check(L);
}
void solve(){
int n;cin >> n;
vt.clear();
check(n);
cout << vt.size() << "\n";
for (auto &g : vt) {
cout << g.size();
for (int x : g) cout << " " << x;
cout << "\n";
}
} 看完点个赞

京公网安备 11010502036488号