记录34
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[30]={};
for(int i=0;i<26;i++){
if(i==18||i==25) a[i]=3;
else if(i>18) a[i]=(i-1)%3;
else a[i]=i%3;
}
int ans=0;
string s;
getline(cin, s);
for (int i=0;i<s.size();i++){
if(s[i]>='a'&&s[i]<='z') ans+=a[s[i]-'a']+1;
if(s[i]==' ') ans++;
}
cout << ans;
return 0;
}
题目传送门
https://www.luogu.com.cn/problem/P1765
突破点
手机的键盘👉九宫格
要按出英文字母就必须要按数字键多下。例如要按出 x 就得按 9 两下,第一下会出 w,而第二下会把 w 变成 x。0 键按一下会出一个空格。👉每个按键会有序号对应字母
思路
- 用桶的思想来表示英文字母跟空格
- 接着开始统计每一个字母跟空格
代码简析
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[30]={};
for(int i=0;i<26;i++){
if(i==18||i==25) a[i]=3;
else if(i>18) a[i]=(i-1)%3;
else a[i]=i%3;
}
...
...
return 0;
}
a[30] 用来存英文字母需要打的次数(0~25)
%3 的范围 0~2, 这样就可以实现三个字母一次循环
注意:因为是0~2,所以后面记得加上一个1,所以是1~3
if(i==18||i==25) a[i]=3;
其中s跟z,需要四次才能打出来,所以要单独讨论
s是第19个,因为是0开始,所以第19个的序号18
else if(i>18) a[i]=(i-1)%3;
从t开始就用三个一计数(z除开)
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[30]={};
for(int i=0;i<26;i++){
if(i==18||i==25) a[i]=3;
else if(i>18) a[i]=(i-1)%3;
else a[i]=i%3;
}
int ans=0;
string s;
getline(cin, s);
for (int i=0;i<s.size();i++){
if(s[i]>='a'&&s[i]<='z') ans+=a[s[i]-'a']+1;
if(s[i]==' ') ans++;
}
cout << ans;
return 0;
}
ans是用来记录的次数
getline(cin, s); 输入带空格的方式
if(s[i]>='a'&&s[i]<='z') ans+=a[s[i]-'a']+1; 其中s[i]-'a'是字母的编号 +1是因为从0计数要加1
补充
在CSP算法竞赛中,处理带空格的输入是常见需求。以下分条说明各种输入方式及其适用场景:
一、C++风格推荐方法
1.
getline(cin, str)- 首选方案
功能 :读取整行内容(包含空格),直到遇到换行符
\n特点:自动丢弃换行符,不将其存入字符串
注意 :若之前用过
cin>>读取数据,需先处理残留换行符
cppstring s; getline(cin, s); // 读取"hello world 2024"2.
cin.getline(arr, size)- 字符数组版本
功能:读取一行到字符数组,可指定最大长度
安全:防止缓冲区溢出
cppchar buf[105]; cin.getline(buf, 100); // 最多读取99个字符+'\0'
二、C风格方法
3.
fgets(arr, size, stdin)- 安全之选
功能:从标准输入读取一行,可含空格
特点 :会保留换行符
\n,需手动去除安全:必须指定缓冲区大小
cppchar buf[105]; fgets(buf, 100, stdin); // 包含\n buf[strlen(buf)-1] = '\0'; // 去掉末尾换行符4.
gets()- 绝对禁用
危险:不检查数组边界,易导致缓冲区溢出
状态:C++11起已被移除,CSP中禁止使用
三、逐个字符读取
5.
getchar()循环读取
适用:需要精确控制输入或处理不规则格式
示例:读取到行末或文件结束
cppchar c; string s; while((c = getchar()) != '\n' && c != EOF) { s += c; }
四、关键注意事项
⚠️ 换行符残留问题
当
cin>>与getline()混用时:
cppint n; cin >> n; // 输入后按回车,\n留在缓冲区 string s; getline(cin, s); // 会读到残留的\n,导致读空行 // 解决方案1:在getline前加 cin.ignore(); // 或 cin.get() // 解决方案2:统一使用getline,再用stringstream转换类型📌 常见输入模式处理
单行带空格字符串 :直接用
getline()先读数字再读字符串:
cppint n; cin >> n; cin.ignore(); // 关键! string s; getline(cin, s);不确定行数的多行读取:
cppstring line; while(getline(cin, line)) { // 读到文件结束 // 处理逻辑 }
五、CSP竞赛推荐模板
cpp#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); // 加速,但混用C/C++输入时需小心 // 场景1:纯字符串行 string s; getline(cin, s); // 场景2:数字+空格字符串 int n; cin >> n; cin.ignore(); // 必须! string line; getline(cin, line); return 0; }
总结 :优先使用
getline(cin, str),注意处理换行符残留,避免使用危险的gets()。