目录
1.string类型相关知识点学习
4.技巧:字符串转化为数值来比较大小
3.矩阵技巧:偏移量
2.数学知识:曼哈顿距离
1.string类型相关知识点学习
字符串读取方法:
1.cin读取字符串,在遇到不合法字符(空格或者回车)时停止。
#include <iostream>
using namespace std;
int main()
{
string str;
cin >> str; // 输入字符串时,遇到空格或者回车就会停止
cout << str << endl; // 输出字符串时,遇到空格或者回车不会停止,遇到'\0'时停止
printf("%s\n", str.c_str());
return 0;
}
2.getline读取一整行字符串:
字符数组用fgets,字符串用getline:
#include <iostream>
using namespace std;
int main()
{
char str[100];
fgets(str, 100, stdin); // 注意fgets不会删除行末的回车字符
//cin.getline (str, 100); 这个也行
cout << str << endl;
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << s << endl;
return 0;
}
字符串常用函数:
(1) strlen(str),求字符串的长度
(2) strcmp(a, b),比较两个字符串的大小,a < b返回-1,a == b返回0,a > b返回1。这里的 比较方式是字典序!
(3) strcpy(a, b),将字符串b复制给从a开始的字符数组。
(4)insert 函数
在原串下标为pos的字符前插入字符串str
insert (pos, str);
str从下标为pos1开始数的n个字符插在原串下标为pos的字符前
insert ( pos, str, pos1, n);
在原串下标为pos的字符前插入n个字符c
insert (pos, n, c);
遍历字符数组中的字符:
正常的for语句:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
string str= "hello world!";
for (int i = 0; str(i); i ++ )
cout << a[i] << endl;
return 0;
}
基于范围的for语句:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "hello world";
for (char c: s)//无法改变s中的值
cout << c << endl;
for (char& c: s)//可以改变s中的值
c = 'a';
cout << s << endl;
return 0;
}
2.技巧:字符串转化为数值来比较大小
eg:循环相克令是一个两人玩的小游戏。
令词为“猎人、狗熊、枪”,两人同时说出令词,同时做出一个动作——猎人的动作是双手叉
腰;狗熊的动作是双手搭在胸前;枪的动作是双手举起呈手枪状。
双方以此动作判定输赢,猎人赢枪、枪赢狗熊、狗熊赢猎人,动作相同则视为平局。
现在给定你一系列的动作组合,请你判断游戏结果。
输入格式
第一行包含整数 N,表示共有 N 组测试数据。
接下来 N 行,每行包含两个字符串,表示一局游戏中两人做出的动作,字符串
为 Hunter
, Bear
, Gun
中的一个,这三个单词分别代表猎人,狗熊和枪。
输出格式
如果第一个玩家赢了,则输出 Player1
。
如果第二个玩家赢了,则输出 Player2
。
如果平局,则输出 Tie
。
猎人赢枪、枪赢狗熊、狗熊赢猎人
->hunter>gun gun>bear bear>hunter
如果令hunter=0,bear=1,gun=2
则hunter+1==bear,bear+1=gun。
但gun+1!=bear。
这里可以用环的思想:
(gun+1)%3==bear
即让三个元素成为一个首尾相接环。
answer:
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int num,p1,p2;
string s1,s2;
scanf("%d",&num);
while(num--)
{
cin>>s1>>s2;
if(s1=="Hunter") p1=0;
else if(s1=="Bear") p1=1;
else p1=2;
if(s2=="Hunter") p2=0;
else if(s2=="Bear") p2=1;
else p2=2;
if(p1==p2) printf("Tie\n");
else if(p1==(p2+1)%3) printf("Player1\n");
else printf("Player2\n");
}
return 0;
}
3.矩阵技巧:偏移量
eg:
输入两个整数 n 和 m,输出一个 n 行 m 列的矩阵,将数字 1 到 n×m 按照回字蛇形填充至矩
阵中。
具体矩阵形式可参考样例。
输入格式
输入共一行,包含两个整数 n 和 m。
输出格式
输出满足要求的矩阵。
矩阵占 n 行,每行包含 m 个空格隔开的整数。
我们只要关注撞墙(即到了边界和遇到非0元素)的情况:
设初始方向为向右。
1.撞到右上方:
方向变为向下。
2.撞到右下方:
方向变为向左。
3.撞到左下方:
方向变为向上。
矩阵的填充方向为:右 -> 下 -> 左 -> 上 ->右 -> 下 -> 左 -> 上 ……
所以矩阵填充的方向可以用数组来表示,且根据是否撞墙来调整填充的方向
dy[]={1,0,-1,0} dx[]{0,1,0,-1};
用来表示偏移量
answer:
#include<iostream>
#include<cmath>
using namespace std;
const int N=100;
int q[N][N];
int main(){
int dy[ ]={1,0,-1,0},dx[ ]{0,1,0,-1};
int row,col,cnt,xn,yn,c=0,a,b;
cin>>xn>>yn;
for(row=0,col=0,cnt=1;cnt<=xn*yn;cnt++){
q[row][col]=cnt;
a=col+dy[c];b=row+dx[c];
if(a<0||a>=yn||b<0||b>=xn||q[b][a])
{
c=(c+1)%4;
a=col+dy[c]; b=row+dx[c];
}
row=b;col=a;
}
for(int i=0;i<xn;i++){
for(int j=0;j<yn;j++){
cout<<q[i][j]<<' ';
}
cout<<endl;
}
return 0;
}
4.数学知识:曼哈顿距离
曼哈顿距离:
eg:
输入一个奇数 n,输出一个由 *
构成的 n 阶实心菱形。
输入格式
一个奇数 n。
输出格式
输出一个由 *
构成的 nn 阶实心菱形。
具体格式参照输出样例。
这是一道找规律的题目,我们可以先画出实心菱形的形状:
n=5
* *** ***** *** *
以最中心的*为原点计算每个点到它的曼哈顿距离。
可以看到曼哈顿距离小于2(即5/2)的格子都打上了*
所以我们可以推出要打出实心菱形就是把曼哈顿距离小于n/2的格子填充上*。
answer:
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int x,y,n;
cin>>n;
x=n/2;
y=n/2;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(abs(x-i)+abs(y-j)<=n/2) {
cout<<'*';
}else{
cout<<' ';
}
}
cout<<endl;
}
return 0;
}
同理我们还可以打出空心菱形:
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int x,y,n;
cin>>n;
x=n/2;
y=n/2;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(abs(x-i)+abs(y-j)==n/2) {
cout<<'*';
}else{
cout<<' ';
}
}
cout<<endl;
}
return 0;
}