5.17练习总结

今天做了四道题,但是这里只放三道,最后一道题我不会,第一题和第二题有错误。

t1:找试场

题目描述:小王同学在坐标系的(0,0)处,但是他找不到考试的试场,于是一边走路一边问路, 每个被问路的人会告诉他一个指令(包括走路或转弯),现在请编一个程序,显示他每次走 路后的坐标(转弯后坐标不变,所以不必显示坐标)。 初始方向向 y 轴正半轴!!

一开始觉得这道题很简单嘛,实际上这题的确很简单,直接放代码把:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long n,a=0,b=0,q=0,hhh=0;
int dx[5]={0,1,0,-1};//这是用来在需要走相应步数时对应的方向
int dy[5]={1,0,-1,0};
string s;
int main(){
    scanf("%lld",&n);
    for(int i=0;i<n;i++){
        cin>>s;
        if(s[0]>='0'&&s[0]<='9'){
            long long hh=0;
            for(int i=0;i<s.length();i++){//如果输入的是数字而不是指令那么久用一个变量把这个数字存起来
                hh*=10;
                hh+=s[i]-'0';
            }
            a+=hh*dx[q];//x和y都按照指令行走相应的步数
            b+=hh*dy[q];
            printf("(%lld,%lld)
",a,b);//每次行走都要输出
            hhh=1;//本来我也忘了,如果只是转了方向而没有走路的话,那么坐标就是(0,0),我一开始没有让他输出,不过这不是什么大问题,用一个标记数组标记一下最后判断就好了,所以我就直接加上了。
        }
        else{//如果这不是数字而是指令
            if(s=="left"){//那么判断是这两种里面的哪一种指令,如果是left就让变量q--(这是为了让他走路的时候走正确的方向)
                if(q>0) q--;
                else q=4;q--;
            }
            if(s=="right"){//如果是right就让变量q++
                if(q<3) q++;
                else q=0;
            }
        }
    }
    if(hhh==0) printf("(0,0)
");//如果没有走路的话就输出(0,0)
    return 0;
}

但是我犯了一个致命错误:

因为如果else后面不加大括号只能执行一条语句(这个我也是才刚刚知道,不然也不可能错了)

所以我们把p=4;p--;这两条语句改成p=3;这一条就AC了。

t2:监考老师

题目描述:在一个大试场里,有 n 行 m 列的考生,小王和众多同学正在考试,这时,有一部分考生 作弊,当然,监考老师能发现他们。但是只有一个监考老师,他由于高度近视,只能发现与 他同行同列的作弊者,而且由于监考老师年老体弱,在考试过程中无法移动。现在已知 n*m 个考生中谁在作弊,请帮监考老师找一个位置,可以发现最多的作弊者(监考老师可以和某 个考生在同一位置)。如果监考老师的位置上的考生在作弊,那么监考老师先前后看,发现 他作弊,再左右看,又发现他作弊,算做发现 2 个考生作弊。

这题一样,我也是手残了,本来很简单,只要遍历一遍每次判断就可以了:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a[1010][1010],maxx=0;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            scanf("%d",&a[i][j]);
        }
    }//以上为输入
    for(int i=0;i<n;i++){//遍历一遍数组
        for(int j=0;j<m;j++){
            int hh=0;//每次都定义一个用来计数的变量hh
            for(int k=0;k<n;k++){//先遍历这一个老师所在的点的一行中有多少个作弊的
                if(a[k][j]==1) hh++;
            }
            for(int k=0;k<n;k++){//先遍历这一个老师所在的点的一列中有多少个作弊的
                if(a[i][k]==1) hh++;
            }
            maxx=max(maxx,hh);//最后比较大小,保存更大的
        }//因为我们用了两个for循环分别遍历了老师所在的行和列,而老师所在的点呢,就被判断了两次,所以我们也不用可以去根据题目要求判断什么的了
    }
    printf("%d
",maxx);//输出
    return 0;
}

但是大家一定能发现一个致命的问题:

因为这个for跟上面那个for很像嘛,所以我就直接复制过来了,但是我没有改掉k<n,导致我直接就WA了。

把k<n改为k<m就AC了。

t3:难题

题目描述:小王在考试中遇到一道难题:方程 a1+a2+„„+an=m 的非负整数解有几个,请你帮他算 一下(这也可以算作他作弊吧)。

深搜就好,我直接放代码了:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,ans=0,a[1010][1010];
void dfs(int idx,int hh){
    if(idx==n){//如果到达了一个目标
        if(hh==0) ans++;//如果到达了最终目标,就让总个数加加
        return;//返回上一层
    }
    for(int i=0;i<=m;i++){
        if((hh-i)>=0&&idx+1<=n){//这个判断不加也没关系,不过加了可以省不少步骤
            dfs(idx+1,hh-i);//调用dfs函数进行深搜
        }
    }
    return;
}
int main(){
    scanf("%d%d",&n,&m);
    dfs(0,m);//调用深搜函数
    printf("%d
",ans);
    return 0;
}

以上仅是个人对于这几道题的全部思路与想法,如果有什么不对的地方,还请各位大佬及时向我纠正。

原文地址:https://www.cnblogs.com/dgdger/p/12906302.html