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)

原文地址:https://www.cnblogs.com/qq1337822982/p/8598145.html