• CCF能力认证历届第二题


    201809-2. 买菜

    解题思路:

    主要就是判断小H和小W的装车时间段是否有重叠区间。关于判断重叠区间,对于给定的两个区间(a,b)和(c,d),显然当且仅当a≤d且b≥c时才会有重叠区间,而重叠区间长度L为min(b,d)-max(a,c),把所有重叠区间的长度进行累加求和,就可以知道俩人可以聊多长时间。

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 void Input(int a[][2],int n);  //用来输入装车时间
     5 
     6 int main()
     7 {
     8     int n;
     9     cin >> n;   //时间段的数量
    10     int H[n][2];   //小H的各个装车的时间段
    11     Input(H,n);
    12     int W[n][2];   //小W的各个装车的时间段
    13     Input(W,n);
    14     int ans = 0;
    15     for (int i = 0; i < n; i++)
    16     {
    17         for (int j = 0; j < n; j++)
    18         {
    19             //对于给定的两个区间(a,b)和(c,d),显然当且仅当a≤d且b≥c时才会有重叠区间
    20             if(H[i][0]<=W[j][1]&&H[i][1]>=W[j][0])   //判断有无重叠区间
    21             {
    22                 //重叠区间长度L为min(b,d)-max(a,c)
    23                 ans += min(H[i][1],W[j][1])-max(H[i][0],W[j][0]);    //加上重叠区间
    24             }
    25         }
    26     }
    27     cout << ans << endl;
    28     return 0;
    29 }
    30 
    31 void Input(int a[][2],int n)
    32 {
    33     for (int i = 0; i < n; ++i)
    34     {
    35         cin >> a[i][0] >> a[i][1];
    36     }
    37 }

    201803-2. 碰撞的小球

    解题思路:

    先吐槽一波,这道物理题也太长了吧,我截了3张图再把它们用photoshop拼起来的。建立俩个数组分别用来存取小球的位置和方向(规定方向向右为1,向左为-1)。每秒每个小球移动一个单位长度,小球每次移动之后都需要判断①该小球是否和其他小球发生碰撞,若发生了碰撞则碰撞的俩者都要改变方向;②该小球是否到达边界,若到达了边界也改变方向。最后输出每个小球的位置即可。     

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int N,L,T;   //N为小球的个数,L为线段长度,计算T秒后小球的位置
     7     cin >> N >> L >> T;
     8     int a[N];   //n个小球的位置
     9     int b[N];   //n个小球的方向
    10     for (int i = 0; i < N; i++)
    11     {
    12         cin >> a[i];
    13         b[i] = 1;  //规定向右为1,向左为-1
    14     }
    15     while(T--)
    16     {
    17         for (int i = 0; i < N; i++)
    18         {
    19             a[i] += b[i];     //每个位置每次移动一个单位长度
    20         }
    21         for (int i = 0; i < N; i++)
    22         {
    23             for (int j = i+1; j < N; j++)  //判断小球是否和其他小球发生碰撞,若碰撞了则俩者均改变方向
    24             {
    25                 if(a[i]==a[j])
    26                 {
    27                     b[i] = -b[i];
    28                     b[j] = -b[j];
    29                 }
    30             }
    31             if(a[i]==0||a[i]==L)  //判断小球是否到达边界,若到达边界则改变方向
    32             {
    33                 b[i] = -b[i];
    34             }
    35         }
    36     }
    37     for (int i = 0; i < N; i++)
    38     {
    39         cout << a[i] << " ";
    40     }
    41     return 0;
    42 }

    201712-2. 游戏

    解题思路:

    这是一个约瑟夫环问题,我用队列来实现的。n个小朋友依次入队(假设围成了一个圈),count为计数器(用来记录报数)。排在队首的小孩报的数若是k的倍数或其个位数为k,则将该小孩淘汰。若小孩没有被淘汰则把他放入队尾继续转圈报数。

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 bool Out(int count,int k)   //判断小孩是否被淘汰
     5 {
     6     if(count%k==0||count%10==k) //若一个小朋友报的数为k的倍数或个位数为k
     7     {
     8         return true;  //将该小孩淘汰出局
     9     }
    10     return false;
    11 }
    12 
    13 int main()
    14 {
    15     int n,k;
    16     cin >> n >> k;
    17     queue<int> q;
    18     int count = 0;   //计数器
    19     for (int i = 1; i <= n; i++)   
    20     {
    21         q.push(i);  //n个小朋友依次入队
    22     }
    23     while(q.size()>1)
    24     {
    25         count++;
    26         int temp = q.front();  //读取队首元素
    27         q.pop();    //删除队首元素
    28         if(!Out(count,k))   //若该小孩没有被淘汰,则加入队尾继续转圈报数
    29         {
    30             q.push(temp);
    31         }
    32     }
    33     cout << q.front() << endl;
    34     return 0;
    35 }

     201709-2. 公共钥匙盒

     

    解题思路:

    先定义一个教师结构体Teacher配合vector一起使用,里面有钥匙编号、使用钥匙的时间、标识符(0借1还),再创建一个钥匙列表key。vector先按还钥匙的时间升序排列,若还取钥匙的时间相同,则按先借后还排列,若多位老师还钥匙,则按钥匙编号升序排列。排序好以后,用for-each循环对vector进行遍历进行借还钥匙操作即可。最后对钥匙列表进行输出即可。

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 struct Teacher
     5 {
     6     int key;    //钥匙编号
     7     int time;   //使用钥匙的时间
     8     int flag;   //设置标识符,0借,1还
     9 };
    10 
    11 bool Cmp(Teacher a,Teacher b)
    12 {
    13     if(a.time != b.time)
    14     {
    15         return a.time < b.time;    //先按还取钥匙的时间升序排序
    16     }
    17     else if(a.flag != b.flag)
    18     {
    19         return a.flag > b.flag;
    20     }
    21     else    //若多位老师还钥匙
    22     {
    23         return a.key < b.key;     //则按钥匙编号升序排列
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     ios::sync_with_stdio(false);   //取消cin和stdin的同步
    30     int N,K;
    31     int key[1001];   //钥匙列表
    32     cin >> N >> K;
    33     vector<Teacher> v;
    34     for (int i = 1; i <= N; i++)
    35     {
    36         key[i] = i;     //对钥匙进行赋初值
    37     }
    38     for (int i = 0; i < K; ++i)
    39     {
    40         int w,s,c;  //老师要使用的钥匙编号w、开始上课的时间s和上课的时长c
    41         cin >> w >> s >> c;
    42         v.push_back({w,s,0});    //
    43         v.push_back({w,s+c,1});   //
    44     }
    45     sort(v.begin(),v.end(),Cmp);   
    46     for(auto it:v)   
    47     {
    48         if(it.flag == 0)  //借钥匙
    49         {
    50             for (int i = 1; i <= N; i++)
    51             {
    52                 if(key[i] == it.key)
    53                 {
    54                     key[i] = 0;   //钥匙被借走了
    55                     break;
    56                 }
    57             }
    58         }
    59         else    //还钥匙
    60         {
    61             for (int i = 1; i <= N; i++)
    62             {
    63                 if(key[i] == 0)
    64                 {
    65                     key[i] = it.key;   //把钥匙归还
    66                     break;
    67                 }
    68             }
    69         }
    70     }
    71     for (int i = 1; i <= N; i++)
    72     {
    73         cout << key[i] << " ";
    74     }
    75     return 0;
    76 }

     201703-2. 学生排队

    解题思路:

    这题是利用vector来操作的,先对学生序号进行初始化,然后删除指定位置的学号,并将该指定学号插入到它的最终位置,最后对vector进行输出即可。

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int n,m;//n个学生,m次移动 
     7     cin >> n >> m;
     8     vector<int> v; 
     9     for(int i = 0; i < n; i++)
    10     {
    11         v.push_back(i+1);   //初始化学生序号
    12     }
    13     for(int i = 0; i < m; i++)
    14     {
    15         int p,q;//学号p,移动q 
    16         cin >> p >> q;
    17         int j = 0;
    18         while(i < m)
    19         {
    20             if(v[j]==p)
    21             {
    22                 v.erase(v.begin()+j);//删除指定位置的学号
    23                 v.insert(v.begin()+j+q,p);//用insert函数将指定学号插入到最终位置。
    24                 break;
    25             }
    26             j++;
    27         }
    28     } 
    29     for(int i = 0; i < v.size(); i++)
    30     {
    31         cout << v[i] << " ";
    32     }
    33     return 0;
    34 }

    201612-2. 工资计算

    解题思路:

    对于这题,我这个菜鸡毫无方法可言,直接暴力破解。

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int T,S; // T为税后工资,S为税前工资
     7     cin >> T;
     8     if (T <= 3500)
     9     {
    10         S = T;
    11     }
    12     else if (T <= 4955)
    13     {
    14         S = ((T - 3500) / 97) * 100 + 3500;
    15     }
    16     else if (T <= 7655)
    17     {
    18         S = (T - 4955) / 90 * 100 + 5000;
    19     }
    20     else if (T <= 11255)
    21     {
    22         S = (T - 7655) / 80 * 100 + 8000;
    23     }
    24     else if (T <= 30755)
    25     {
    26         S = (T - 11255) / 75 * 100 + 12500;
    27     }
    28     else if (T <= 44755)
    29     {
    30         S = (T - 30755) / 70 * 100 + 38500;
    31     }
    32     else if (T <= 61005)
    33     {
    34         S = (T - 44755) / 65 * 100 + 58500;
    35     }
    36     else
    37     {
    38         S = (T - 61005) / 55 * 100 + 83500;
    39     }
    40     cout << S << endl;
    41     return 0;
    42 }

    201609-2. 火车购票

    解题思路:

    用数组a来记录每排卖出的座位数,初始化为0。立一个flag用来判断能不能买到同一排相邻的座位。若需要购入的票数p加该排卖出的座位数小于5,则说明能买到同一排的相邻座位, 将flag改为true,并输出座位号。如果不能买到同一排的相邻座位,就按座位号升序来查找空座位。

    100分代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int n;  //n为购票指令的数量
     7     cin >> n;
     8     int a[20];   //记录每排卖出的座位数
     9     memset(a,0,sizeof(a));   //全部初始化为0
    10     while(n--)
    11     {
    12         int p;   //需要购入的票数
    13         cin >> p;
    14         bool flag = false;   //flag为true表示能买到同一排相邻的座位
    15         for (int i = 0; i < 20; i++)   //假设能买到同一排的相邻座位
    16         {
    17             if(a[i]+p <= 5)
    18             {
    19                 for (int j = 0; j < p; j++)
    20                 {
    21                     if(j != p-1)
    22                     {
    23                         cout << i*5+a[i]+j+1 << " ";
    24                     }
    25                     else
    26                     {
    27                         cout << i*5+a[i]+j+1 << endl;
    28                     }
    29                 }
    30                 a[i] += p;
    31                 flag = true;
    32                 break;
    33             }
    34         }
    35         if(!flag)  //如果不能买到同一排的相邻座位,就按座位号从小到大来寻找空座位
    36         {
    37             int num = 0;
    38             for (int i = 0; i < 20; i++)
    39             {
    40                 if(a[i] < 5)
    41                 {
    42                     num++;
    43                     if(num == p)
    44                     {
    45                         cout << i*5+a[i]+1 << endl;
    46                     }
    47                     else
    48                     {
    49                         cout << i*5+a[i]+1 << " ";
    50                     }
    51                     a[i]++;
    52                     i--;  //这一排可能还有空座位
    53                 }
    54             }
    55         }
    56     }
    57     return 0;
    58 }

    未完待续····

  • 相关阅读:
    windows下的SASS/Compass的安装与卸载
    玩转HTML5移动页面(优化篇)
    小谈数组去重
    前端问题解答
    JavaScript使用封装
    JavaScript使用接口
    JavaScript精要(系列)
    JavaScript DOM节点和文档类型
    JavaScript数组类型
    JavaScript函数表达式
  • 原文地址:https://www.cnblogs.com/m17773572025/p/10068220.html
Copyright © 2020-2023  润新知