ccf-csp历届第一题题解 (一)14-17年 (ง •_•)ง

ccf-csp认证历届签到题题解(Java&C++)


  正所谓“靖康耻,尤未雪,柿子还得挑软的捏~” , 还记得我第一次考ccf时直接报零结束>.< , 所以这里总结了历届的第一题题解和思路供刚刚接触ccf的小伙伴们参考~

题目(传送门~app内无效哦):

201403-1相反数    201409-1相邻数对
201412-1门禁系统   201503-1图像旋转
201509-1数列分段   201512-1数位之和
201604-1折点计数   201609-1最大波动
201612-1中间数    201703-1分蛋糕


试题 & AC代码:

  PS:本文主要面向第一次接触ccf-csp的同学,主要理解思路,大部分代码为Java版,必要时给出C++版,两者虽然有语法上的区别,但是并不影响理解,相信你看了Java或是C++的其中一种也很快会写出对应的另一种。
  大家只需要注意Java代码的Scanner与in.nextInt()相当于c++的cin,System.out.println()相当于cout。

  • 相反数
    相反数tips: 如果用c++,取绝对值用abs函数(浮点型用fabs),记得添加头文件#include<math.h>。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = 0;
        N = in.nextInt();
        int[] table = new int[10005];
        int temp,ans = 0;
        for(int i=0;i<N;i++){
            temp = in.nextInt();
            if(table[Math.abs(temp)]==1){
                ans++;
            }
            table[Math.abs(temp)]++;
        }
        System.out.println(ans);
    }
}
  • 相邻数对
    相邻对数tips:散列,将输入的数值映射到数组的下标,输入一个数,在对应下标位置加一,再次遍历数组,如果相邻两个位置的值都为1,就是相邻数对,计数加一。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int index=0,N=0;
        int[] table = new int[10005];
        N = in.nextInt();
        for(int i=0;i<N;i++){
            index = in.nextInt();
            table[index]++;
        }
        int ans = 0;
        for(int i=0;i<10005;i++){
            if(table[i]==1&&table[i+1]==1){
                ans++;
            }
        }
        System.out.println(ans);
    }
}
  • 门禁系统
    门禁系统tips:一个数组记录每位读者出现的次数即可,读者编号就是数组下标。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int[] reader = new int[1005];
        int n,number;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        for(int i=0;i<n;i++){
            number = in.nextInt();
            reader[number]++;
            System.out.print(reader[number]+" ");
        }
    }
}
  • 图像旋转
    图像旋转tips:Java版代码要进行输入优化,直接使用Scanner会导致内存超限,只能拿到90分。C++版本则没有这个坑,只要搞清楚旋转后数组下标的变化即可。
//c++版
#include<bits/stdc++.h>
using namespace std;
int main(){
    int r,c;
    cin>>r>>c;
    int graph[r][c];
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
            cin>>graph[i][j];
        }
    }
    for(int i=c-1;i>=0;i--){
        for(int j=0;j<r;j++){
            cout<<graph[j][i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

Java版代码点这里>.<,有详细介绍~~

  • 数列分段
    201509tips:记录输入前后两个数的值,不一样就计数加一。
import java.util.Scanner;

class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int curr,prev = -1,ans = 0;
        for(int i=0;i<n;i++){
            curr = sc.nextInt();
            if(curr!=prev){
                ans++;
            }
            prev = curr;
        }
        System.out.println(ans);
    }
}
  • 数位之和
    201512tips:这里提供两种方法,c++经典模除法,java可以直接读入一行,每一位转换成整数相加。
//c++版
#include<bits/stdc++.h>
using namespace std;
int main(){
    int num,ans=0;
    cin>>num;
    while(num>0){
        ans+=num%10;
        num/=10;
    }
    cout<<ans<<endl;
    return 0;
}
//java版
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String num = new String(sc.nextLine());
        int ans = 0;
        for(int i=0;i<num.length();i++){
            ans+=(num.charAt(i)-'0');
        }
        System.out.println(ans);
    }
}
  • 折点计数
    201604tips:与上题一样,记录输入前后两个数的值,只不过这里还要做差,记录出是上升的趋势还是下降的趋势,前后的变化趋势不同,计数加一。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int prev = sc.nextInt();
        //只有一个数据的情况单独考虑
        if(n==1){
            System.out.println(0);
        }else{
        int curr = sc.nextInt();
        int ans = 0,change = (curr-prev);
        //change*(curr-prev)<0说明前后数据的变化趋势不同,ans+1
        for(int i=0;i<n-2;i++){
            prev = curr;
            curr = sc.nextInt();
            if(change*(curr-prev)<0){
                ans++;
            }
            change = (curr-prev);
        }
        System.out.println(ans);
        }
    }
}
  • 最大波动
    201609tips:先算出相邻两天的差值,然后打擂比较找出最大值(ans)。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int prev = sc.nextInt();
        int curr = sc.nextInt();
        int ans = Math.abs(curr-prev);
        for(int i=0;i<n-2;i++){
            prev = curr;
            curr = sc.nextInt();
            if(Math.abs(curr-prev)>ans){
                ans = Math.abs(curr-prev);
            }
        }
        System.out.println(ans);
    }
}
  • 中间数
    201612tips:没什么好说的,暴力就完事了。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        for(int i=0;i<n;i++){
            nums[i] = sc.nextInt();
        }
        boolean falg = false;
        for(int num : nums){
            int gt = 0,lt = 0;
            for(int i=0;i<n;i++){
                if(num>nums[i])
                    gt++;
                if(num<nums[i])
                    lt++;
            }
            if(gt==lt){
                System.out.println(num);
                falg = true;
                break;
            }
        }
        if(!falg)
            System.out.println(-1);
        }
}
  • 分蛋糕
    201703tips:这里需要注意分到最后蛋糕可能不到k,但是按题目要求计数要加一。
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int sum = 0,ans = 0;
        for(int i=0;i<n;i++){
            sum += sc.nextInt();
            if(sum>=k){
                sum = 0;
                ans++;
            }
        }
        if(sum!=0)
            ans++;
        System.out.println(ans);
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mymel_晗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值