C++第一周心得

发布于:2022-11-06 ⋅ 阅读:(409) ⋅ 点赞:(0)

目录

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 行,每行包含两个字符串,表示一局游戏中两人做出的动作,字符串

        为 HunterBearGun 中的一个,这三个单词分别代表猎人,狗熊和枪。

        输出格式

        如果第一个玩家赢了,则输出 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;
            }