zoukankan      html  css  js  c++  java
  • 20180318CSP比赛

    一共五道题

    1.跳一跳

    2.小球碰撞

    3.指令匹配?

    4.下棋

    5.二次查找?

    我只做了1,2,4 三个题 不知道结果如何。记录一下~

    跳一跳

    题目描述:输入一串数字 1代表跳上了但不在中间 2代表跳在中间 0代表没跳上下一个 计算本局跳一跳成绩

    输入样例:1 1 2 2 2 1 1 2 2 0

    输出:22  (1+1+2+4+6+1+1+2+4)

    #include<iostream>
    using namespace std;
    int main(){
        int a[30];
        int score=0;
        int figure=0,num=0;
        int flag=0;
        for(int i=0;i<30;i++){
            cin>>a[i];
            num++;
            if(a[i]==0) break;
            }
        for(int j=0;j<num;j++){
            if(a[j]==1) {
                flag=0;
                figure=1;
                score+=figure;
            }
            else if (a[j]==2 ) {
                flag++;
                figure=2*flag;
                score+=figure;
            }
        }
        cout<<score; 
        return 0;
    }


    出现的问题:刚开始输入一串数字时,我的方法是

      for(int i=0;a[i]!=0;i++){

        cin>>a[i];

        num++;

      }   但是一直不能输出正确的结果2333 在考试的电脑上输入 1 1  2 2 2 11 2 2 0 但是得到的数组却是 1 1 2 2 2 1 1 (2 2 丢失) 在我自己的电脑上只得到了1

     当然了,这种写法是错误的。因为a[i]的值是后来才输入的 所以判断是否a[i]!=0的时候a[i[还是未知的...考试的时候没有反应过来。其实用while循环也可以的。

    程序的思路是 用figure记录这次跳的分数,score是总分。flag的作用是记录是否连续跳中间,在中间连续跳了几次。

    小球碰撞

    题目描述:数轴上有一个长为L的绳子,左端点在原点,右端点是L。L是一个偶数,绳子上有n个小球,它们的初始位置也都是偶数,开始时他们都以1(长度单位/时间单位)的速度向右匀速运动,到达两端点就按原速率反向运动,小球之间碰撞时也按原速率反向运动。 求t时刻各个小球的位置。

    分析与提示:L是偶数,小球的初始坐标为偶数都是为了简化题的难度。提示中说小球碰撞的时间都是整数的时间,也不存在三个小球相互碰撞的情况。

    思路:既然小球碰撞的时间是整数的时间,那就时间每增一,计算每个小球的位置和方向。满足碰撞条件就改变其方向。

    #include<iostream>
    using namespace std;
    int main(){
        int n,l,t;
        cin>>n>>l>>t;
    
        int *right=new int[n];
        int *now=new int[n];
        int *first=new int [n];
        for(int i=0;i<n;i++){
            cin>>first[i];
            right[i]=1;
        } 
    
        for(int k=0;k<t;k++){
            
            for(int j=0;j<n;j++){
                first[j]=(first[j]+1)%(2*l);
                
                if(first[j]<l){
                    now[j]=first[j];
                    right[j]=1;
                }
                else if(first[j]>=l && first[j]<2*l){
                    now[j]=2*l-first[j];
                    right[j]=0;
                }
    
            
            }
            for(int i1=0;i1<n;i1++){
                 for(int j1=i1+1;j1<n;j1++){
                     if(now[i1]==now[j1] && right[i1]+right[j1]==1 ){
                         int t=first[i1];
                            first[i1]=first[j1];
                            first[j1]=t;
                 }
             }
         }
         
        }
    
        for(int m=0;m<n;m++){
            cout<<now[m]<<" ";
        }
    
        delete []now;
        delete []right;
        delete []first;
        return 0;
    }

    我的思路是用first数组记录每个小球的相对移动量(mod   2*L),用now数组计算每个小球的位/置坐标。因为小球可以有两个方向的移动,那么first数组某元素的值如果在0-L之间,就说明此小球正在向右移动,如果在L-2L之间就说明在向左移动。

    我需要先解释一下first数组的含义。假设小球到右端点不反弹,保持向右的匀速直线运动。那么当它距离原点为2倍L的时候,实际上这时它正好回到了原点。相当于我们把小球折回的这段路程展开了。而它距离原点超过2倍L的时候,它又向右匀速运动了。因此所有的小球的运动都可以被分成两个部分:距离原点0 -> L:向右匀速 ; 距离原点 L -> 0:向左匀速。first数组中元素的值其实就是一去一回中小球离原点的路程(不是位移)。因为如果first值等于2L,就相当于在原点,接下来都是重复的过程。因此first数组值的取值范围就是0-2L (左闭右开区间) 即[0, 2L)。 值为0到L的小球向右匀速运动,值为L到2L的小球向左匀速运动。端点值需要特别注意 0:左端点 速度向右  L:右端点 速度向左

    right数组记录每个小球的方向。值为0 方向向左,值为1 方向向右。(后来我发现first和right作用是相同的,要一个就好了)

    因为题干说最开始所有的小球都向右匀速。因此把right数组每个元素值都设为1。外层的for循环是对时间的循环(时间每次增加1,看所有小球的位置),内层的for循环是对小球的遍历,看每个小球的位置。遍历得到每个小球的位置,就可以找是否有小球位置相同速度方向相反了(判断速度方向是否相反,可以把right[r1]+right[j1]==1改成first[r1]+first[j1]==2*L),这是发生碰撞的充要条件。碰撞后两球交换速度。

    最开始first[j]=(first[j]+1)%(2*l);这步我开始写错了 我是这样写的:if(right[j]==1) first[j]=(first+1)%(2*l) ;else first[j]=(first-1)%(2*l) ; 注意是一秒一秒看的 所以是加减1而不是加减k(严格的说是加减1乘以速度 ,但速度也为1)这样看起来好像很对,但其实是我把first数组和now数组混淆了。如果按错误的写法,first值永远不能达到L-2L 。

    这个算法就是在模拟整个过程。

    下棋

    题目描述:3*3的棋盘上,Alice和Bob一起下棋。Alice先下x,Bob后下o。谁先脸上三个谁赢。分数的设定是:如果Alice赢了,分数是棋盘上空格数加一;如果Bob赢了,分数是负的(棋盘上空格数加一)。如果棋下满了谁也没连上三个,就平局,分数为0。输入玩的局数以及每局当前的状态,计算当前状态的分数。(两个人都是按照最优的方案下棋)

    输入:n局棋 和每局棋的状态。0代表空,1代表Alice下的x,2代表Bob下的o

    输出:n局棋当前状态下的得分

    输入样例:

    3

    1 2 1

    2 1  2

    0 0 0

    2 1 1

    0 2 1

    0 0 2 

    0 0 0

    0 0 0

    0 0 0

    输出:

    3

    -4

    0

    注意点:如果当前状态下谁都没连上三个棋,但是空的位置上恰好有一个位置能让下一个出棋的人连上三个,由于两个人都是按照最优的方案下棋,当前成绩就是这个人赢。

    对于3*3棋盘,以a[9]表示,能连上三个的下标有:012,036,048,147,246,258,345,678。因此我暴力枚举......

    #include<iostream>
    using namespace std;
    int kong(int *a){
        int count=0;
        for(int k=0;k<9;k++){
            if(a[k]==0) count++;
        }
        return count;
    }
    int shewin(int *a){
        int countA=0,countB=0;
        for(int m=0;m<9;m++){
            if(a[m]==1) countA++;
            else if(a[m]==2) countB++;
        } int flag=0;
        if(countA==countB&&countA==0)return flag;
        
        if(a[0]==a[1]&&a[1]==a[2]&&a[0]!=0){
                if(a[0]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[0]==a[3]&&a[3]==a[6]&& a[0]!=0){
                if(a[0]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[0]==a[4]&&a[4]==a[8]&& a[0]!=0){
                if(a[0]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[1]==a[4]&&a[4]==a[7]&& a[1]!=0){
                if(a[1]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[2]==a[4]&&a[4]==a[6]&& a[4]!=0){
                if(a[2]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[2]==a[5]&&a[5]==a[8]&& a[2]!=0){
                if(a[2]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[4]==a[3]&&a[3]==a[5]&& a[3]!=0){
                if(a[3]==1) flag=1;
                else  flag=-1;
                return flag;
            }
            else if(a[6]==a[7]&&a[8]==a[6]&& a[7]!=0){
                if(a[7]==1) flag=1;
                else  flag=-1;
                return flag;
            }
         if(countA>countB){
            
            if(a[0]==a[1]&&a[0]==2&&a[2]==0){
                a[2]=2;flag=-1;return flag;
            }
            else if(a[0]==a[2]&&a[0]==2&&a[1]==0){
                a[1]=2;flag=-1;return flag;
            }
            else if(a[2]==a[1]&&a[1]==2&&a[0]==0){
                a[0]=2;flag=-1;return flag;
            }
            else if(a[0]==a[3]&&a[0]==2&&a[6]==0){
                a[6]=2;flag=-1;return flag;
            }else if(a[0]==a[6]&&a[0]==2&&a[3]==0){
                a[3]=2;flag=-1;return flag;
            }else if(a[3]==a[6]&&a[3]==2&&a[0]==0){
                a[0]=2;flag=-1;return flag;
            }else if(a[0]==a[4]&&a[0]==2&&a[8]==0){
                a[8]=2;flag=-1;return flag;
            }else if(a[0]==a[8]&&a[0]==2&&a[4]==0){
                a[4]=2;flag=-1;return flag;
            }else if(a[8]==a[4]&&a[4]==2&&a[0]==0){
                a[0]=2;flag=-1;return flag;
            }else if(a[4]==a[1]&&a[4]==2&&a[7]==0){
                a[7]=2;flag=-1;return flag;
            }else if(a[1]==a[7]&&a[1]==2&&a[4]==0){
                a[4]=2;flag=-1;return flag;
            }else if(a[4]==a[7]&&a[4]==2&&a[1]==0){
                a[1]=2;flag=-1;return flag;
            }else if(a[2]==a[5]&&a[2]==2&&a[8]==0){
                a[8]=2;flag=-1;return flag;
            }else if(a[8]==a[5]&&a[5]==2&&a[2]==0){
                a[2]=2;flag=-1;return flag;
            }else if(a[2]==a[8]&&a[2]==2&&a[5]==0){
                a[5]=2;flag=-1;return flag;
            }else if(a[2]==a[4]&&a[2]==2&&a[6]==0){
                a[6]=2;flag=-1;return flag;
            }else if(a[2]==a[6]&&a[2]==2&&a[4]==0){
                a[4]=2;flag=-1;return flag;
            }else if(a[4]==a[6]&&a[4]==2&&a[2]==0){
                a[2]=2;flag=-1;return flag;
            }else if(a[3]==a[4]&&a[3]==2&&a[5]==0){
                a[5]=2;flag=-1;return flag;
            }else if(a[4]==a[5]&&a[4]==2&&a[3]==0){
                a[3]=2;flag=-1;return flag;
            }else if(a[3]==a[5]&&a[3]==2&&a[4]==0){
                a[4]=2;flag=-1;return flag;
            }else if(a[6]==a[7]&&a[6]==2&&a[8]==0){
                a[8]=2;flag=-1;return flag;
            }else if(a[7]==a[8]&&a[7]==2&&a[6]==0){
                a[6]=2;flag=-1;return flag;
            }else if(a[6]==a[8]&&a[6]==2&&a[7]==0){
                a[7]=2;flag=-1;return flag;
            }
        }else if(countA==countB){
            if(a[0]==a[1]&&a[0]==1&&a[2]==0){
                a[2]=1;flag=1;return flag;
            }
            else if(a[0]==a[2]&&a[0]==1&&a[1]==0){
                a[1]=1;flag=1;return flag;
            }
            else if(a[2]==a[1]&&a[1]==1&&a[0]==0){
                a[0]=1;flag=1;return flag;
            }
            else if(a[0]==a[3]&&a[0]==1&&a[6]==0){
                a[6]=1;flag=1;return flag;
            }else if(a[0]==a[6]&&a[0]==1&&a[3]==0){
                a[3]=1;flag=1;return flag;
            }else if(a[3]==a[6]&&a[3]==1&&a[0]==0){
                a[0]=1;flag=1;return flag;
            }else if(a[0]==a[4]&&a[0]==1&&a[8]==0){
                a[8]=1;flag=1;return flag;
            }else if(a[0]==a[8]&&a[0]==1&&a[4]==0){
                a[4]=1;flag=1;return flag;
            }else if(a[8]==a[4]&&a[4]==1&&a[0]==0){
                a[0]=1;flag=1;return flag;
            }else if(a[4]==a[1]&&a[4]==1&&a[7]==0){
                a[7]=1;flag=1;return flag;
            }else if(a[1]==a[7]&&a[1]==1&&a[4]==0){
                a[4]=1;flag=1;return flag;
            }else if(a[4]==a[7]&&a[4]==1&&a[1]==0){
                a[1]=1;flag=1;return flag;
            }else if(a[2]==a[5]&&a[2]==1&&a[8]==0){
                a[8]=1;flag=1;return flag;
            }else if(a[8]==a[5]&&a[8]==1&&a[2]==0){
                a[2]=1;flag=1;return flag;
            }else if(a[2]==a[8]&&a[2]==1&&a[5]==0){
                a[5]=1;flag=1;return flag;
            }else if(a[2]==a[4]&&a[2]==1&&a[6]==0){
                a[6]=1;flag=1;return flag;
            }else if(a[2]==a[6]&&a[2]==1&&a[4]==0){
                a[4]=1;flag=1;return flag;
            }else if(a[4]==a[6]&&a[4]==1&&a[2]==0){
                a[2]=1;flag=1;return flag;
            }else if(a[3]==a[4]&&a[3]==1&&a[5]==0){
                a[5]=1;flag=1;return flag;
            }else if(a[4]==a[5]&&a[4]==1&&a[3]==0){
                a[3]=1;flag=1;return flag;
            }else if(a[3]==a[5]&&a[5]==1&&a[4]==0){
                a[4]=1;flag=1;return flag;
            }else if(a[6]==a[7]&&a[6]==1&&a[8]==0){
                a[8]=1;flag=1;return flag;
            }else if(a[7]==a[8]&&a[7]==1&&a[6]==0){
                a[6]=1;flag=1;return flag;
            }else if(a[6]==a[8]&&a[6]==1&&a[7]==0){
                a[7]=1;flag=1;return flag;
            }
        }
        return flag;
    }
    int main(){
        int n;
        int a[9];
        cin>>n;
        for(int i=0;i<n;i++){
            for(int j=0;j<9;j++){
                cin>>a[j];
            }
            if(shewin(a)==1)cout<<kong(a)+1<<endl;
            else if(shewin(a)==0) cout<<0<<endl;
            else cout<<(-1)*(kong(a)+1)<<endl;
            
        }
    
    
        return 0;
    }

    flag=1,Alice赢;flag=0,平局;flag=-1,Bob赢。

    差一步就赢的时候,要把这步下了。
    在考试的过程中,我发现了一个自己一直没有注意到的错误:if(a[0]==a[1]==2)是不可以的 而a[0]=a[1]=2是可以的 所以必须写成 if(a[0]==a[1] && a[0](或者a[1])==2)

  • 相关阅读:
    正则表达式语法介绍
    关系型数据库和非关系型数据库的简单对比
    lambda函数
    java基础系列--Exception异常处理
    springBoot基础系列--properties配置
    spring基础系列--JavaConfig配置
    java基础系列--Calendar类
    java基础系列--Date类
    一个特殊的List去重问题的解决方案
    Java学习笔记
  • 原文地址:https://www.cnblogs.com/qq1337822982/p/8598145.html
Copyright © 2011-2022 走看看