记录56
#include<bits/stdc++.h>
using namespace std;
string a,b;
int main(){
cin>>a>>b;
int cnt=0,f=0,t=0;
for(int i=0;i<a.size();i++){
if(a[i]!=b[i]){
f=++f%2;
if(f==1) t=i;//第一个不同状态
if(f==0) cnt+=i-t;//一直反转到第二个不同状态
}
}
cout<<cnt;
return 0;
}
题目传送门
https://www.luogu.com.cn/problem/P8597
突破点
桌上放着排成一排的若干硬币。我们用
*表示正面,用o表示反面(是小写字母,不是零),比如可能情形是**oo***oooo,如果同时翻转左边的两个硬币,则变为oooo***oooo。现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
思路
- 硬币的反转实际上是一种波动
- 两行硬币中连续相同的状态看成一种状态
- 将不同的状态给翻面
A:**********
B:o****o****可以简化看成
A:****
B:o*o*
两次翻面即可把o给波动过去
第一次翻面:翻面1下
第二次翻面:翻面4下
四种情况
**翻面变成oo
*o翻面变成o*
o*翻面变成*o
oo翻面变成**
要完成的操作就是把硬币给波动成目标状态
代码简析
#include<bits/stdc++.h>
using namespace std;
string a,b;
int main(){
cin>>a>>b;
int cnt=0,f=0,t=0;
for(int i=0;i<a.size();i++){
if(a[i]!=b[i]){
f=++f%2;
if(f==1) t=i;//第一个不同状态
if(f==0) cnt+=i-t;//一直反转到第二个不同状态
}
}
cout<<cnt;
return 0;
}
string a(初始状态),b(目标状态);
int cnt=0(计算一共翻面多少下),f=0(硬币状态情况),t=0(记录下不同状态);
for(int i=0;i<a.size();i++){} 👉 遍历硬币状态
if(a[i]!=b[i]){} 👉 找到不同的硬币
f=++f%2; 👉 记录找到不同的状态的情况
if(f==1) t=i; 👉 第一个不同状态
if(f==0) cnt+=i-t; 👉 找到第二个不同状态时,加上中间翻面多少下
补充
字符变化规律发现完全指南
一、字符变化规律的四大类型(90%考题原型)
类型1:周期性变化(考频★★★★★)
特征:字符按固定周期重复
周期1:单个字符循环(
a→b→c→a→...)周期2:字符串整体循环(
abc→bcd→cde→...)周期3:位置映射循环(
第1个→第3个→第5个→...→回到第1个)识别技巧:写下前10-15个字符,看重复单元
类型2:对称性变化(考频★★★★☆)
特征:关于中心点/中心线对称
左右对称:
abcdedcba上下对称:打印菱形、沙漏
旋转对称:字符串左旋k位后与原串匹配
识别技巧:画坐标系,用
abs(i-center)计算对称距离
类型3:递推性变化(考频★★★☆☆)
特征:当前状态由前面状态推导
斐波那契式:
f[i] = f[i-1] + f[i-2]加密式:
c[i] = (c[i-1] + k) % 26组合式:
str[i] = str[i/2] + str[i%2]识别技巧:写下前5-10项,找递推关系
类型4:映射式变化(考频★★★★☆)
特征:字符→字符的固定映射
凯撒密码:
a→d, b→e, c→f...自定义映射:题目给转换表
ASCII码映射:
c = c + k识别技巧:建立
map[原字符] = 新字符字典
二、发现规律的五步法(实战方法论)
Step 1:暴力打表,写下前N项(N≥10)
// 别急着找规律,先打印出来! string s = "a"; for (int i = 0; i < 20; i++) { cout << s << endl; s = next(s); // 按题目规则生成下一个 } // 观察输出: // a // bc // def // ghij // 发现:长度=步数+1,首字母每次+1竞赛工具:在草稿纸上手写5-10步,圈出重复单元
Step 2:抽象坐标,建立数学模型
把字符位置抽象为
(i,j)坐标:// 打印菱形示例 // 观察第i行:先输出空格,再输出字符 // 空格数 = |i - center| // 字符数 = k - |i - center| for (int i = 1; i <= n; i++) { int spaces = abs(i - center); // 到中心垂直距离 int chars = k - spaces; // 字符个数 // 输出spaces个空格 // 输出chars个字符 }核心公式:距离 = abs(当前位置 - 中心位置)
Step 3:寻找周期,取模定位
// 字符循环:a→b→c→...→z→a→... char next(char c) { return (c - 'a' + 1) % 26 + 'a'; // 周期26 } // 字符串循环:"abc"→"bca"→"cab"→"abc"... // 周期=3 string rotate(string s) { return s.substr(1) + s[0]; }竞赛技巧:发现规律后,用取模%实现循环,避免if判断
Step 4:构建映射表(暴力打表)
// 题目给转换规则:a→d, b→e, c→f... char trans[26]; for (int i = 0; i < 26; i++) { trans['a' + i] = 'd' + i; // 建立映射 } // 转换字符串 for (char &c : s) { c = trans[c - 'a']; // O(1)查表 }优点:O(1)查询,比if-else快
Step 5:归纳通项公式(数学推导)
// 观察输出: // 第0行: a // 第1行: bc (b='a'+1, c='b'+1) // 第2行: def (d='a'+3, e='d'+1, f='e'+1) // 推导:第i行首字符 = 'a' + i*(i+1)/2 // 第i行第j个字符 = 首字符 + j int start = 'a' + i * (i + 1) / 2; for (int j = 0; j <= i; j++) { printf("%c", start + j); }竞赛技巧:首项、公差、等差数列公式
三、竞赛实战技巧(救命稻草)
技巧1:草稿纸暴力模拟
画坐标轴:横纵坐标标1~n
标关键点:中心点、边界点
算距离:用绝对值找规律
圈重复单元:观察周期长度
技巧2:绝对值
abs()是图形万能钥匙// 菱形:abs(i-center) + abs(j-center) == k // 正方形:max(abs(i-center), abs(j-center)) == k // 十字:abs(i-center) == 0 || abs(j-center) == 0技巧3:取模
%是循环万能钥匙// 字符循环:a→b→...→z→a char c = 'a' + (i % 26); // 字符串循环:反复输出"abc" string pattern = "abc"; char c = pattern[i % pattern.size()];技巧4:二维转一维(降维打击)
// 将二维坐标映射到一维下标 int idx = i * m + j; // 矩阵按行展开 // 一维转二维 int i = idx / m, j = idx % m;技巧5:对拍验证(小数据)
// 写两个版本:暴力版和规律版 // 对随机小数据(n≤10)验证输出是否一致 for (int n = 1; n <= 10; n++) { string s1 = brute_force(n); string s2 = pattern(n); assert(s1 == s2); // 不一致则报错 }
四、CSP-J高频图形规律题
题型1:打印菱形
// 规律:到中心曼哈顿距离 = k for (int i=1; i<=n; i++) { for (int j=1; j<=n; j++) { int dx = abs(i - center); int dy = abs(j - center); printf("%c", dx + dy == k ? '*' : ' '); } printf("\n"); }题型2:字符蛇形矩阵
// 规律:i+j为偶数的位置升序,奇数降序 // 或:位置i从0开始,字符 = 'a' + (i % 26) for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { printf("%c", 'a' + (i * m + j) % 26); } printf("\n"); }题型3:字符串加密
// 规律:每个字符+密钥,循环回'a' char encrypt(char c, int key) { return (c - 'a' + key) % 26 + 'a'; }
五、一句话总结
字符规律 = 暴力打表 + 绝对值算距离 + 取模做循环 + 不等式判边界,先在草稿纸上写10步找重复单元,再抽象坐标系套公式。
545

被折叠的 条评论
为什么被折叠?



