zoey
点击国内主页可以让浏览速度加快哦 ~ !

CCF&&CSP 2017-09 (前2道)

2019-09-14 csp C/C++ 堆栈法 贪心
Word count: 2.5k | Reading time: 10min




问题 A: 打酱油

题目

问题 A: 打酱油
试题编号: 201709-1 试题名称: 打酱油 时间限制:1.0s 内存限制:256.0MB 问题描述:
问题描述
  小明带着N元钱去买酱油。酱油10块钱一瓶,商家进行促销,每买3瓶送1瓶,或者每买5瓶送2瓶。请问小明最多可以得到多少瓶酱油。
输入格式
  输入的第一行包含一个整数N,表示小明可用于买酱油的钱数。N是10的整数倍,N不超过300。
输出格式
  输出一个整数,表示小明最多可以得到多少瓶酱油。
样例输入
40
样例输出
5
样例说明
  把40元分成30元和10元,分别买3瓶和1瓶,其中3瓶送1瓶,共得到5瓶。
样例输入
80
样例输出
11
样例说明
  把80元分成30元和50元,分别买3瓶和5瓶,其中3瓶送1瓶,5瓶送2瓶,共得到11瓶。




原题链接

More info:Question


贪心

贪心算法的定义
———— 贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

所以,够买5瓶的时候先买5瓶,剩下的在去买3瓶的,最后剩下的无法参加优惠活动的,按实际10元/瓶并入结果。


AC源码(c++)

我的AC源码
1
2
3
4
5
6
7
8
9
10
#include<iostream>
using namespace std;
int N;
int main() {
while (cin >> N) {
int num = N / 10;
cout << num + num / 5 * 2 + (num - num / 5 * 5) / 3 << endl;
}
return 0;
}

问题 B: 公共钥匙盒

题目

问题 B: 公共钥匙盒
试题编号:201709-2 试题名称:公共钥匙盒 时间限制:1.0s 内存限制:256.0MB 问题描述:
问题描述
  有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。
  钥匙盒一共有N个挂钩,从左到右排成一排,用来挂N个教室的钥匙。一串钥匙没有固定的悬挂位置,但钥匙上有标识,所以老师们不会弄混钥匙。
  每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。
  今天开始的时候钥匙是按编号从小到大的顺序放在钥匙盒里的。有K位老师要上课,给出每位老师所需要的钥匙、开始上课的时间和上课的时长,假设下课时间就是还钥匙时间,请问最终钥匙盒里面钥匙的顺序是怎样的?
输入格式
  输入的第一行包含两个整数N, K
  接下来K行,每行三个整数w, s, c,分别表示一位老师要使用的钥匙编号、开始上课的时间和上课的时长。可能有多位老师使用同一把钥匙,但是老师使用钥匙的时间不会重叠。
  保证输入数据满足输入格式,你不用检查数据合法性。
输出格式
  输出一行,包含N个整数,相邻整数间用一个空格分隔,依次表示每个挂钩上挂的钥匙编号。
样例输入
5 2
4 3 3
2 2 7
样例输出
1 4 3 2 5
样例说明
  第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。
  每个关键时刻后的钥匙状态如下(X表示空):
  时刻2后为1X345;
  时刻3后为1X3X5;
  时刻6后为143X5;
  时刻9后为14325。
样例输入
5 7
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9
样例输出
1 2 3 5 4
评测用例规模与约定
  对于30%的评测用例,1 ≤ N, K ≤ 10, 1 ≤ wN, 1 ≤ s, c ≤ 30;
  对于60%的评测用例,1 ≤ N, K ≤ 50,1 ≤ wN,1 ≤ s ≤ 300,1 ≤ c ≤ 50;
  对于所有评测用例,1 ≤ N, K ≤ 1000,1 ≤ wN,1 ≤ s ≤ 10000,1 ≤ c ≤ 100。




原题链接

More info:Question


向量

(参考自马大欧c++基础之向量Vector)
头文件:

1
#include <vector>

和string一样,也算是一种容器,而且同属于STL(standard template library)里的好基友

初始化向量

  1. 初始化向量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            vector<int> a ;                                //声明一个int型向量a
    vector<int> a(10) ; //声明一个初始大小为10的向量
    vector<int> a(10, 1) ; //声明一个初始大小为10且初始值都为1的向量
    vector<int> b(a) ; //声明并用向量a初始化向量b
    vector<int> b(a.begin(), a.begin()+3) ; //将a向量中从第0个到第2个(共3个)作为向量b的初始值
    也可以用数组来初始化向量

    int n[] = {1, 2, 3, 4, 5} ;
    vector<int> a(n, n+5) ; //将数组n的前5个元素作为向量a的初值
    vector<int> a(&n[1], &n[4]) ; //将n[1] - n[4]范围内的元素作为向量a的初值

向量元素的输出和访问

  1. 向量元素的输出和访问

普通的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<vector>

using namespace std ;

int main()
{
vector<int> a(10, 0) ; //大小为10初值为0的向量a

//对其中部分元素进行输入
cin >>a[2] ;
cin >>a[5] ;
cin >>a[6] ;

//全部输出
int i ;
for(i=0; i<a.size(); i++)
cout<<a[i]<<" " ;

return 0 ;
}

在输出上,还可以使用迭代器,类似城管一样,一个一个不漏地弄出来vector里面的元素

比如在这种申明形式下

1
vector <int> a(b.begin(),b.begin()+3);

中,可以使用城管iterator

1
2
3
4
//全部输出
vector<int>::iterator t ;
for(t=a.begin(); t!=a.end(); t++)
cout<<*t<<" " ;

向量的基本操作

  1. 向量的基本操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1>. a.size()                 //获取向量中的元素个数


2>. a.empty() //判断向量是否为空


3>. a.clear() //清空向量中的元素


4>. 复制
a = b ; //将b向量复制到a向量中


5>. 比较
保持 ==、!=、>、>=、<、<= 的惯有含义 ;
如: a == b ; //a向量与b向量比较, 相等则返回1


6>. 插入 - insert
①、 a.insert(a.begin(), 1000); //将1000插入到向量a的起始位置前

②、 a.insert(a.begin(), 3, 1000) ; //将1000分别插入到向量元素位置的0-2处(共3个元素)

③、 vector<int> a(5, 1) ;
vector<int> b(10) ;
b.insert(b.begin(), a.begin(), a.end()) ; //将a.begin(), a.end()之间的全部元素插入到b.begin()前


7>. 删除 - erase
①、 b.erase(b.begin()) ; //将起始位置的元素删除
②、 b.erase(b.begin(), b.begin()+3) ; //将(b.begin(), b.begin()+3)之间的元素删除


8>. 交换 - swap
b.swap(a) ; //a向量与b向量进行交换

二维向量

  1. 二维向量
1
vector< vector<int> > b(10, vector<int>(5));        //创建一个10*5的int型二维向量

输入输出的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vector< vector<int> > b(10, vector<int>(5, 0)) ;

//对部分数据进行输入
cin>>b[1][1] ;
cin>>b[2][2] ;
cin>>b[3][3];

//全部输出
int m, n ;
for(m=0; m<b.size(); m++) //b.size()获取行向量的大小
{
for(n=0; n<b[m].size(); n++) //获取向量中具体每个向量的大小
cout<<b[m][n]<<" " ;
cout<<"\n" ;
}

AC源码(c++)

参考的JasonCeng_CCF2017.9-2公共钥匙盒 ,分享一下

我的AC源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef struct teacher{
int keynum;
int time;
int typeflag;//0借1还
};
int N, K, w, s, c;
vector<teacher> t;
bool cmp(teacher& a,teacher& b) {
if (a.time != b.time) { return (a.time < b.time ? true : false); } //按时间先后顺序操作
else if (a.typeflag != b.typeflag) { return (a.typeflag > b.typeflag ? true : false); } //同时的时候,先还后借
else { return (a.keynum < b.keynum ? true : false); } //若同时同操作类型,则优先钥匙编号小的那一个
}
int main() {
cin >> N >> K;
int* key_res = new int[N + 1];
for (int i = 0; i <= N; i++) key_res[i] = i;//钥匙数组&输出结果
while (K--) { //入向量操作
cin >> w >> s >> c;
teacher cmp_t;
cmp_t.keynum = w;
cmp_t.time = s;
cmp_t.typeflag = 0;
t.push_back(cmp_t);
cmp_t.keynum = w;
cmp_t.time = s + c;
cmp_t.typeflag = 1;
t.push_back(cmp_t);
}
sort(t.begin(), t.end(), cmp);
for (int i = 0; i < t.size(); i++) {
for (int j = 1; j <= N; j++) {
if (0 == t[i].typeflag && key_res[j] == t[i].keynum) { //借钥匙
key_res[j] = -1;
break;
}
else if (1 == t[i].typeflag && key_res[j] == -1) { //还钥匙
key_res[j] = t[i].keynum;
break;
}
}
}
for (int i = 1; i <= N; i++) cout << key_res[i] << " ";
cout << endl;
return 0;
}

Author: Zoey

Link: https://zoey1038569979.github.io/2019/09/14/ccf_201709/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
Android端选择本地视频并上传到SpringMVC服务端
NextPost >
CCF&&CSP 2019-03 (前2道)
CATALOG
  1. 1. 问题 A: 打酱油
    1. 1.1. 题目
    2. 1.2. 原题链接
    3. 1.3. 贪心
    4. 1.4. AC源码(c++)
  2. 2. 问题 B: 公共钥匙盒
    1. 2.1. 题目
    2. 2.2. 原题链接
    3. 2.3. 向量
      1. 2.3.1. 初始化向量
      2. 2.3.2. 向量元素的输出和访问
      3. 2.3.3. 向量的基本操作
      4. 2.3.4. 二维向量
    4. 2.4. AC源码(c++)