CCF 第二题
Posted twomeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF 第二题相关的知识,希望对你有一定的参考价值。
最小差值 另解
先对数据进行排序,求相邻数据的最小值
打酱油
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 using namespace std; 8 /* 9 题目: 10 用时:tomato * 11 思路: 12 */ 13 14 15 int main() 16 { 17 int n; // n <=300 18 while (cin>>n) 19 { 20 int x = n / 10 ; 21 int five = ( x / 5 ) * 2; 22 int thr = (x % 5) / 3 ; 23 cout << five+thr + x <<endl; 24 } 25 26 27 return 0; 28 }
工程做法:使用常量为了程序的通用性
/* CCF201709-1 打酱油 */ #include <stdio.h> const int ONE = 1; const int TWO = 2; const int FIVE = 5; const int THREE = 3; const int PRICE = 10; int main(void) { int n, group1, group2, group3; scanf("%d", &n); group1 = n / PRICE / FIVE; group2 = (n - group1 * PRICE * FIVE) / PRICE / THREE; group3 = (n - group1 * PRICE * FIVE - group2 * PRICE * THREE) / PRICE; printf("%d ", group1 * (FIVE + TWO) + group2 * (THREE + ONE) + group3); return 0; }
分蛋糕
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 using namespace std; 8 /* 9 题目:分蛋糕 10 思路: 11 */ 12 13 14 int main() 15 { 16 int n,k; 17 int cake = 0; 18 int part = 0; 19 int num = 0; 20 while (cin>>n>>k) 21 { 22 while (n--) 23 { 24 cin >> part; 25 cake += part; 26 if (cake >= k ) 27 { 28 cake = 0 ; 29 num ++; 30 } 31 } 32 if (cake < k ) 33 { 34 num ++; 35 } 36 cout << num <<endl; 37 } 38 39 40 return 0; 41 }
100分答案:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int n, k, ans = 0, s = 0, a; 7 cin >> n >> k; 8 while (n--) 9 { 10 cin >> a; 11 s += a; 12 if (s >= k) 13 { 14 s = 0; 15 ans++; 16 } 17 } 18 if (s)ans++; 19 cout << ans; 20 return 0; 21 }
第一次做的只有20分,经过改进发现,
if (cake)
不要写成if (cake < k )
,因为如果是刚刚好,cake应该为0,大于0的话才是蛋糕不够的的情况。要注意边界问题
另外能不使用数组而使用一次性变量的情况就使用变量,这不浪费内存呢么?
中间数
*
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 using namespace std; 8 /* 9 题目:分蛋糕 10 思路: 11 */ 12 13 bool equals(int a[],int n,int mid) 14 { 15 int lit = 0; 16 int big = 0; 17 for (int i = 0 ;i < (n-1)/2 ; i++) 18 { 19 if (a[i] < mid) 20 lit++; 21 } 22 for (int i = (n-1)/2+1 ;i < n ; i++) 23 { 24 if (a[i] > mid) 25 big++; 26 } 27 if (lit == big) 28 return true; 29 } 30 31 int main() 32 { 33 int n; 34 int a[1000]; 35 bool flag = 1; 36 while ( cin >> n ) 37 { 38 for (int i = 0;i<n;i++) 39 cin >> a[i]; 40 41 sort(a,a+n); 42 if ( n % 2 != 0 ) 43 { 44 int mid = a[(n-1)/2]; 45 if (equals(a,n,mid)){ 46 cout << mid <<endl; 47 flag = 0; 48 } 49 50 } 51 else 52 { 53 int mid1= a[(n-1)/2]; 54 int mid2= a[(n+1)/2]; 55 if (equals(a,n,mid1)){ 56 cout <<mid1 <<endl; 57 flag = 0; 58 } 59 else 60 if (equals(a,n,mid2)) 61 { 62 cout <<mid2<<endl; 63 flag = 0; 64 } 65 } 66 if (flag) 67 cout << -1 <<endl; 68 69 } 70 71 return 0; 72 }
分数 : 80
满分答案:减去与两侧相同的数
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 using namespace std; 8 /* 9 题目:分蛋糕 10 思路: 11 */ 12 13 14 const int N = 1000; 15 int a[N]; 16 int main() 17 { 18 int n; 19 while ( cin >> n ) 20 { 21 for (int i = 0;i<n;i++) 22 cin >> a[i]; 23 24 sort(a,a+n); 25 int mid = a[n/2]; 26 int left = n/2; 27 int right = n - left - 1; 28 for (int i = 0 ;i < n/2 ; i++) 29 if (a[i] == mid ) 30 left -- ; 31 for (int i = n/2+1 ;i < n; i++) 32 if (a[i] == mid ) 33 right -- ; 34 35 if (left == right) 36 cout << mid <<endl; 37 else 38 cout << -1<<endl; 39 } 40 return 0; 41 }
最大波动
1 * 不用数组,三个变量解决问题 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <string> 6 #include <stdio.h> 7 #include <iomanip> 8 using namespace std; 9 /* 10 题目: 11 思路: 12 */ 13 14 const int N = 1000; 15 int a[N]; 16 17 int main() 18 { 19 int n; 20 int minN = 0; 21 while (cin >>n) 22 { 23 for (int i=0;i < n;i++) 24 { 25 cin >> a[i]; 26 } 27 for (int i = 0 ;i<n-1;i++) 28 { 29 if (abs(a[i+1] - a[i])> minN ) 30 { 31 minN = abs(a[i+1]-a[i]); 32 } 33 } 34 cout << minN <<endl; 35 } 36 return 0; 37 } 38 * 不需要使用数组的方法, 先输入第一个数,后面的数循环输入 39 int main(void) 40 { 41 int n, first, second, delta, maxval=0; 42 43 // 输入n,输第1个数(从逻辑上来说应该写两句,为了简洁只需要写一句) 44 scanf("%d%d", &n, &first); 45 46 while(--n) { 47 // 输入第2至第n个数 48 scanf("%d", &second); 49 50 // 求差值(波动值),取绝对值,求最大值 51 delta = second - first; 52 if(delta<0) 53 delta = -delta; 54 maxval = MAX(maxval, delta); 55 56 first = second; 57 } 58 59 // 输出结果 60 printf("%d ", maxval); 61 62 return 0; 63 }
折点计数
1 * 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <string> 6 #include <stdio.h> 7 #include <iomanip> 8 using namespace std; 9 /* 10 题目: 11 思路: 12 */ 13 14 15 int main() 16 { 17 // 求左边大右边大或左边小右边小的点的个数 18 int n; 19 int l, m ,r; 20 int num = 0; 21 while (cin >> n) 22 { 23 cin >>l>>m; 24 for (int i=0;i<n-2;i++) 25 { 26 cin >> r; 27 if ((l < m && r < m) || (l > m && r > m )) 28 num ++; 29 l = m; m = r; 30 } 31 cout << num <<endl; 32 33 } 34 return 0; 35 }
游戏
vector 没做出来,生气
1. 首先想到vector,注意vector的循环方法 迭代器+size()判断
2. 使用erase的时候应当避免使用迭代器
3. 如果不使用STL,需要做一个变量标记
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <algorithm> 6 #include <vector> 7 #define maxSize 20 8 #define ERROR -1 9 using namespace std; 10 /* 11 CCF :2017-12-2 12 Time : 游戏 13 Date : 2018/3/14 14 15 */ 16 struct stu 17 { 18 int num; 19 int id; 20 }; 21 int main() 22 { 23 24 int n,k; 25 stu s; 26 int i; 27 vector<stu>::iterator iter; 28 while (cin>>n>>k) 29 { 30 vector<stu> vec; 31 for (int i = 0 ;i < n ; i++) 32 { 33 s.id = i+1; 34 vec.push_back(s); 35 } 36 37 38 int i = 0; 39 while (vec.size() > 1) 40 { 41 for (iter = vec.begin(); iter != vec.end();i++) 42 { 43 iter->num = i+1; 44 cout << "num :"<<iter->num<< " id :"<<iter->id<<endl; 45 46 if (iter->num%k == 0 || iter->num % 10 == k) 47 { 48 cout << iter->id <<"号小朋友报数" << iter->num << "被淘汰" <<endl; 49 iter = vec.erase(vec.begin()+ iter->id - 1); 50 } 51 else 52 iter ++; 53 54 } 55 } 56 cout << vec[0].id; 57 58 } 59 return 0; 60 } 61 * 正确: 62 #include <iostream> 63 #include <string.h> 64 #include <stdio.h> 65 #include <stdlib.h> 66 #include <algorithm> 67 #include <vector> 68 #define maxSize 20 69 #define ERROR -1 70 using namespace std; 71 /* 72 CCF :2017-12-2 73 Time : 游戏 74 Date : 2018/3/14 75 76 */ 77 78 int main() 79 { 80 int n,k; 81 cin >> n >> k; 82 vector<int> vec; 83 for (int i=0;i<n;i++) 84 vec.push_back(i+1); 85 int i = -1,no = 0; 86 while (vec.size() > 1){ 87 no ++; 88 i ++; 89 i = i % vec.size(); // ★★★★ 相当于循环的作用 90 if ( no % k == 0 || no % 10 == k) 91 { 92 vec.erase(vec.begin()+i); 93 i--; 94 } 95 96 } 97 cout << vec[0] <<endl; 98 99 return 0; 100 } 101 * 从第一个进队的元素开始取,并pop()弹出队列,如果no符合要求则不行动否则push()到队列中。和学生的顺序无关? 102 while(!q.empty()) { 103 head = q.front(); 104 q.pop(); 105 106 no++; 107 if(no % k == 0 || no % 10 == k) 108 ; 109 else 110 q.push(head); 111 } 112 * 变量标记 113 const int N = 1000; 114 bool flag[N]; 115 116 int main() 117 { 118 int n, k; 119 120 // 读入数据 121 cin >> n >> k; 122 123 // 初始化 124 memset(flag, false, sizeof(flag)); 125 126 // 模拟出局过程 127 int i = -1, no = 0, cnt = n; 128 while(cnt > 1) { 129 i++; 130 i %= n; 131 if(!flag[i]) { 132 no++; 133 if(no % k == 0 || no % 10 == k) { 134 flag[i] = true; 135 136 cnt--; 137 } 138 } 139 } 140 return 0; 141 }
ISBN
首先想到string,字符与整数的转化过程不要忘记!
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 #include <vector> 8 #include <queue> 9 using namespace std; 10 /* 11 题目:ISBN号码 12 思路: 13 14 */ 15 16 17 int main() 18 { 19 string s; 20 cin >> s; 21 int c = 1; 22 int sum = 0; 23 for (int i = 0 ; i < s.length()-1 ;i ++) 24 { 25 if (s[i] != ‘-‘){ 26 sum += (s[i]-‘0‘)*c; 27 c++; 28 } 29 } 30 int c1 = sum % 11; 31 char cc; 32 // 逻辑上的错误! 33 // 如果cc = x,不应该被认为是不正确的一类 34 if (c1 == 10) 35 cc = ‘X‘; 36 else 37 cc = ‘0‘+c1; // 统一转化为字符 38 39 if ( cc == s[s.length()-1]) 40 cout << "Right" << endl; 41 else 42 { 43 s[s.length()-1] = cc; 44 cout <<s<< endl; 45 } 46 47 48 49 return 0; 50 }
窗口
窗口和点击操作用结构体实现,窗口从上到下的顺序用order数组表示,为了标记每个窗口的位置,给窗口结构体增加num序号,便于进行窗口移动的调整。
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 #include <vector> 8 #include <queue> 9 using namespace std; 10 /* 11 题目:窗口 12 思路: 13 14 */ 15 struct win{ 16 int x1; 17 int y1; 18 int x2; 19 int y2; 20 int no; 21 }win[11]; 22 23 struct point 24 { 25 int x; 26 int y; 27 }point[11]; 28 int order[11]; 29 30 31 int belongToWin(int j,int x,int y) 32 { 33 if ( (x >= win[j].x1 && x <= win[j].x2) &&(y >= win[j].y1 && y <= win[j].y2)) 34 return 1; 35 else 36 return 0; 37 } 38 void moveTo(int j,int n) 39 { 40 // order中移动顺序 41 int t = order[j]; 42 for (int i = j ; i < n-1 ; i++ ) 43 { 44 order[i] = order[i+1]; 45 } 46 order[n-1] = t; 47 } 48 int main() 49 { 50 int N,M; 51 cin >> N >> M; 52 int i; 53 for (i = 0 ; i < N ;i++) 54 { 55 cin >> win[i].x1 >> win[i].y1 >> win[i].x2 >> win[i].y2; 56 win[i].no = i+1; 57 order[i] = i+1; 58 } 59 for ( i = 0 ; i < M ; i++) 60 { 61 cin >> point[i].x >> point[i].y ; 62 } 63 // 对point操作进行循环,每次找出位于最上层(order中大的)的窗口:改变order移动到最外层,输出窗口序号 64 for ( i = 0 ;i < M ; i++) 65 { 66 bool flag = 1; 67 68 for (int j = N-1 ; j >= 0 ; j--) // 从order的上层开始往下找符合点击范围内的 69 { 70 if (belongToWin(j,point[i].x,point[i].y)) 71 { 72 if (j != N-1) 73 { 74 // 不是最外层 75 moveTo(j,N); // 移动到最外层的函数 76 } 77 cout << win[order[N-1]-1].no <<endl; 78 flag = 0; 79 break; 80 } 81 } 82 if (flag) // 都没点击到窗口内 83 cout <<"IGNORED"<<endl; 84 85 } 86 87 88 89 return 0; 90 } 91 * 40 92 // 判断哪个窗口被点击 93 for(int j=0; j<n; j++) { 94 if(win[order[j]].x1 <= point[i].x && point[i].x <= win[order[j]].x2 && 95 win[order[j]].y1 <= point[i].y && point[i].y <= win[order[j]].y2) { 96 // 得到窗口号 97 winno = win[order[j]].winno; 98 99 // 将被点击的窗口移到最前端 100 temp = order[j]; 101 for(int k=j; k>0; k--) 102 order[k] = order[k-1]; 103 order[0] = temp; 104 105 break; 106 } 107 } 108 109 // 输出结果 110 if(winno == -1) 111 cout << "IGNORED" << endl; 112 else 113 cout << winno << endl; 114 }
画图
矩阵用结构体表示,整个画布用数组表示
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 #include <vector> 8 #include <queue> 9 using namespace std; 10 /* 11 题目: 12 思路: 13 14 */ 15 const int N = 101; 16 struct rec 17 { 18 int x1,y1,x2,y2; 19 }rec[N]; 20 21 int paper[N][N] ; 22 // memset(paper,1,sizeof(paper)) 23 24 int main() 25 { 26 int n; 27 int i,j,k; 28 cin >> n ; 29 for ( i = 0 ;i < n ; i++) 30 { 31 cin >> rec[i].x1 >> rec[i].y1 >> rec[i].x2>>rec[i].y2; 32 } 33 for (i = 0 ; i < N ; i++) 34 for (j = 0 ; j < N ;j ++) 35 paper[i][j] = 0; 36 37 for (i = 0 ;i < n ;i++) 38 { 39 for ( j = rec[i].x1 ; j < rec[i].x2 ; j++) 40 for ( k = rec[i].y1 ; k < rec[i].y2 ; k++) 41 { 42 paper[j][k] = 1; 43 } 44 } 45 46 int num = 0; 47 for (i = 0 ; i < N ; i++) 48 for (int j = 0 ; j < N ;j ++) 49 if (paper[i][j]) 50 num ++; 51 52 cout << num <<endl; 53 54 55 56 57 return 0; 58 }
数字排序
每个数字对应一个数量,使用map表示,一次循环输入,map自动排序
排序的工具使用优先队列,但需要创建对应Node结点和cmp函数,自定义优先队列的使用规则
优先队列特殊:大堆输出,所以和正常的cmp函数要反着写
1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <stdio.h> 6 #include <iomanip> 7 #include <vector> 8 #include <queue> 9 #include <map> 10 using namespace std; 11 /* 12 题目: 13 思路: 14 1.出现次数递减 15 2. 出现次数相同时,先输出值小的 16 17 1. 使用map进行统计 18 2. 使用优先队列进行排序 19 20 */ 21 struct Node 22 { 23 int val,c ; 24 }; 25 26 struct cmp{ 27 bool operator()(Node a, Node b){ 28 if(a.c == b.c) return a.val>b.val; 29 return a.c < b.c; 30 } 31 }; 32 int main() 33 { 34 int n; 35 cin >> n; 36 map<int,int> m ; 37 int t; 38 // 1.输入数据统计出现次数 39 for (int i = 0; i < n ; i++){ 40 cin >> t; 41 m[t] += 1; 42 } 43 /*debug*/ 44 // 2. 利用优先队列进行排序 45 // priority_queue<map<int,int>,vector<map<int,int>,cmp> q; 不能把map作为队列元素 46 // 把map集合中的值一对一对取出,存入node中,插入队列 47 priority_queue<Node,vector<Node>,cmp> q; 48 Node no ; 49 map<int,int>::iterator iter ; 50 for (iter = m.begin() ; iter !=m.end() ; iter++) 51 { 52 no.val = iter->first ; 53 no.c = iter->second ; 54 q.push(no); 55 } 56 57 58 59 // print 60 while(!q.empty()){ 61 cout<<q.top().val<<‘ ‘<<q.top().c<<endl; 62 q.pop(); 63 } 64 65 66 67 return 0; 68 }
公共钥匙盒
- 钥匙盒用数组表示,存储钥匙ID,没有则为-1
- 老师的时间、操作不同,对钥匙盒的改变也不同,需要创建坐标轴的元素改变结点Node并初始化,为了排序,使用优先队列存储Node结点,按照自定义排序规则排序。遍历优先队列。
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #define maxSize 20 10 #define ERROR -1 11 using namespace std; 12 /* 13 CCF :2017-12-2 14 Time : 公共钥匙盒(模拟题) 15 思路 : 16 1. 如果在时间坐标轴上标记,某个事件,还/拿,某把钥匙,定义为一个操作节点 17 2. 使用优先队列对操作节点进行排序,时间优先,时间相同先还再取,操作相同钥匙号小的有限 18 3. 遍历优先队列中的操作,定义钥匙盒数组,没有钥匙为-1,利用循环从小到大找空位 19 20 */ 21 const int K = 1001; 22 struct Node 23 { 24 int key; // 钥匙ID 25 int time; // 时间 26 char op;// 还钥匙R,取钥匙G 27 bool operator < (Node a) const 28 { 29 if (time != a.time) 30 { 31 return time > a.time ; 32 }else if (op != a.op){ 33 return op < a.op; 34 } 35 else{ 36 return key > a.key ; 37 } 38 } 39 40 }; 41 42 const int N1 = 10000; 43 int box[N1]; // 钥匙盒子 44 45 int main() 46 { 47 int n,k,c; // n 个房间,k 个老师 48 // 输入老师的信息 49 cin >> n >> k ; 50 51 // 初始化钥匙盒信息 52 memset(box,0,N1); 53 for (int i = 0 ; i < n ; i++) 54 box[i] = i+1; 55 56 // 初始化优先队列,放入取钥匙和拿钥匙操作节点 57 Node a; 58 int last; 59 priority_queue<Node> p; 60 for (int i = 0 ; i < k ; i++ ) 61 { 62 cin >> a.key >> a.time >> last; 63 a.op = ‘G‘; 64 p.push(a); 65 a.time = last + a.time; 66 a.op = ‘R‘; 67 p.push(a); 68 69 } 70 /*debug 71 while (!p.empty()) 72 { 73 a = p.top(); 74 cout << a.key << " "; 75 p.pop(); 76 } 77 */ 78 79 80 // 遍历优先队列 81 while (!p.empty()) 82 { 83 a = p.top(); 84 p.pop(); 85 if (a.op == ‘G‘) 86 { 87 for (int i = 0; i<n;i++) 88 { 89 if (box[i] == a.key) 90 { 91 box[i] = -1; 92 break; 93 } 94 } 95 } 96 if (a.op == ‘R‘) 97 { 98 for (int i=0;i<n;i++) 99 { 100 if (box[i] == -1) 101 { 102 box[i] = a.key; 103 break; 104 } 105 } 106 } 107 } 108 109 // print 110 for (int i = 0 ; i< n-1;i++) 111 { 112 cout << box[i] << " "; 113 } 114 cout <<box[n-1]<<endl; 115 116 117 118 119 120 121 return 0; 122 }
学生排队
vector 出队erase,入队insert,注意的是这两者的具体函数规则
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #define maxSize 20 10 #define ERROR -1 11 using namespace std; 12 /* 13 CCF : 14 Time : 15 思路 : 16 17 */ 18 void print(vector<int> vec) 19 { 20 for (int i= 0;i<vec.size();i++) 21 { 22 cout <<vec[i]<<" "; 23 } 24 } 25 26 int main() 27 { 28 int n; 29 cin >>n; 30 int m; 31 cin >> m; 32 int p,q; 33 34 // 构造队列 35 vector<int> vec; 36 for (int i=0;i<n;i++) 37 { 38 vec.push_back(i+1); 39 } 40 41 vector<int>::iterator iter; 42 for (int i= 0;i<m;i++) 43 { 44 cin >>p >>q; 45 // 对队列进行操作 46 for (iter =vec.begin() ; iter !=vec.end();iter++) 47 { 48 if (*iter == p) 49 break; 50 } 51 if (++iter != vec.end()) 52 { 53 vec.erase(--iter); 54 //print(vec); 55 vec.insert(iter+q,p); 56 // print(vec); 57 } 58 else 59 { 60 vec.pop_back(); 61 // print(vec); 62 iter = vec.end(); 63 vec.insert(iter+q,p); 64 // print(vec); 65 } 66 } 67 68 // print 69 for (int i= 0;i<vec.size();i++) 70 { 71 cout <<vec[i]<<" "; 72 } 73 74 return 0; 75 }
工资计算
分段问题:正着好求,反着则先正着创建一个表格,然后通过表格找到大致范围,然后推回去。
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #define maxSize 20 10 #define ERROR -1 11 using namespace std; 12 /* 13 CCF : 14 Time : 15 思路 : 16 17 */ 18 int gal[10]={0,1500,4500,9000,35000,55000,80000}; 19 float tax[10] ={0,0.03,0.1,0.2,0.25,0.3,0.35,0.45}; 20 int sal[11]={0,3500,4955,7654,11253}; 21 int main() 22 { 23 float t; 24 cin >>t; 25 float a = t - 3500; // 收税工资部分 26 27 float sum = 3500; 28 for (int i=1;i<7 ;i++) 29 { 30 sum += (gal[i]-gal[i-1])*(1-tax[i]); 31 sal[i+1] = sum; 32 } 33 // for (int i = 0;i<8;i++) 34 // cout << sal[i]<<endl; 35 float sum2 = 3500; 36 for (int i = 1;i<8;i++) 37 { 38 if (t<sal[i] && t>sal[i-1]) 39 { 40 a = (t-sal[i-1])/(1-tax[i-1]); 41 sum2 += a; 42 sum2+=gal[i-2]; 43 } 44 if ( t > sal[7]) 45 { 46 a = (t-sal[7])/(1-tax[7]); 47 sum2 +=gal[6]; 48 } 49 } 50 cout << (int)sum2 << endl; 51 52 53 54 55 56 57 58 59 return 0; 60 }
60
1 /* CCF201612-2 工资计算 */ 2 3 #include <iostream> 4 5 using namespace std; 6 7 //#define DEBUG 8 9 int salaryrange[] = {3500, 3500+1500, 3500+4500, 3500+9000, 3500+35000, 3500+55000, 3500+80000 }; 10 // 税前工资的范围 11 int taxrate[] = {3, 10, 20, 25, 30, 35, 45}; 12 const int SIZE = sizeof(salaryrange) / sizeof(int); 13 // 定义长度不定的数组时计算size的方法 14 15 int range[SIZE]; 16 17 int main() 18 { 19 int t, s; 20 21 // 计算税后工资范围 22 range[0] = salaryrange[0]; 23 for(int i=1; i<SIZE; i++) { 24 range[i] = range[i-1] + (salaryrange[i] - salaryrange[i-1]) 25 - (salaryrange[i] - salaryrange[i-1]) * taxrate[i-1] / 100; 26 } 27 28 #ifdef DEBUG 29 for(int i=0; i<SIZE; i++) 30 cout << range[i] << " "; 31 cout << endl; 32 #endif 33 34 // 输入数据: 35 cin >> t; 36 37 // 计算收入范围 38 int i; 39 for(i=0; i<SIZE; i++) 40 if(t <= range[i]) 41 break; 42 43 // 计算税前工资 44 if(i == 0) 45 s = t; 46 else { 47 s = salaryrange[i-1] + (t - range[i-1]) * 100 / (100 - taxrate[i-1]); 48 } 49 50 // 输出结果 51 cout << s << endl; 52 53 return 0; 54 }
消除游戏
对于数组的灵活使用,两个数组,一个是变量标记数组
1 * CCF201512-2 消除游戏 */ 2 3 #include <stdio.h> 4 #include <string.h> 5 6 #define N 30 7 8 int a[N][N], t[N][N]; 9 10 int main(void) 11 { 12 int n, m, i, j; 13 14 scanf("%d%d", &n, &m); 15 for(i=0; i<n; i++) 16 for(j=0; j<m; j++) 17 scanf("%d", &a[i][j]); 18 19 // 对二维数组的灵活运用 20 memset(t, 0, sizeof(t)); 21 // 进行行标记(可以消除则置1) 22 for(i=0; i<n; i++) 23 for(j=0; j<m-2; j++) 24 if(a[i][j]== a[i][j + 1] && a[i][j + 1] == a[i][j +2]) 25 t[i][j] = t[i][j + 1] = t[i][j + 2] = 1; 26 // 进行列标记(可以消除则置1) 27 for(j=0; j<m; j++) 28 for(i=0; i<n-2; i++) 29 if(a[i][j] == a[i + 1][j] && a[i + 1][j] == a[i + 2][j]) 30 t[i][j] = t[i + 1][j] = t[i + 2][j] = 1; 31 32 // 重置矩阵a 33 for(i=0; i<n; i++) 34 for(j=0; j<m; j++) 35 if(t[i][j]) 36 a[i][j] = 0; 37 38 // 输出结果 39 for(i=0; i<n; i++) { 40 for(j=0; j<m; j++) { 41 if(j != 0) 42 printf(" "); 43 printf("%d", a[i][j]); 44 } 45 printf(" "); 46 } 47 48 return 0; 49 }
火车购票
1 #include <iostream> 2 #include <map> 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */ 4 // 火车购票问题 5 using namespace std; 6 const int LINE = 20; 7 const int NUM = 5; 8 int main(int argc, char** argv) { 9 int n,v,start,end,j; 10 cin >> n ; 11 // 一行的座位打包,记录行数以及这行的剩余位置数 12 map<int ,int> m; 13 // m初始化 14 map<int,int>::iterator iter; 15 for (int i = 1 ;i <= LINE ; i++ ) 16 { 17 m[i] = NUM ; 18 } 19 for (int i = 0 ; i < n ; i++) 20 { 21 cin >> v; 22 // 1. 一行内满足购票 23 // 逻辑:优先从小选择一行内的票,一行内从小到大排列 24 for (iter = m.begin() ; iter != m.end() ; iter ++) 25 { 26 if ( iter->second >= v ) 27 { 28 // 分配座位,输出 29 start = (iter->first - 1) * NUM + NUM - iter->second + 1; 30 end = start + v - 1 ; 31 for (j = start ; j < end;j++) 32 { 33 cout << j <<" "; 34 } 35 cout << end << endl; 36 // 是否要删除座位 37 if (iter->second == v ) 38 { 39 m.erase(iter); 40 }else 41 { 42 iter->second = iter->second - v; 43 } 44 v = 0 ; 45 break; 46 } 47 } 48 // 2.多行购票 需要判断是不是最后一个 49 bool isend = false; 50 while (v > 0) 51 { 52 for (iter = m.begin() ; iter!=m.end();iter ++){ 53 if (iter->second >= v ) 54 { 55 // 分配座位,输出 56 start = (iter->first - 1) * NUM + NUM - iter->second + 1; 57 end = start + v - 1 ; 58 for (j = start ; j < end;j++) 59 { 60 cout << j <<" "; 61 } 62 if (!isend) 63 cout << end << " "; 64 else 65 { 66 cout << end << endl; 67 isend = true; 68 } 69 // 是否要删除座位 70 if (iter->second == v ) 71 { 72 m.erase(iter); 73 }else 74 { 75 iter->second = iter->second - v; 76 } 77 78 }else 79 { 80 start = (iter->first - 1) * NUM + NUM - iter->second + 1; 81 end = start + iter->second - 1 ; 82 for (int j = start ; j <= end;j++) 83 { 84 // 一定没有结束 85 cout << j <<" "; 86 } 87 v = v - iter->second; 88 // 要删除座位 89 m.erase(iter); 90 } 91 } 92 93 } 94 95 } 96 return 0; 97 }
俄罗斯方块
coard 记录方格的具体位置,这样不用就4*4遍历了
1 #include <iostream> 2 #include <map> 3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */ 4 5 using namespace std; 6 7 const int ROW = 15; 8 const int COL = 10; 9 const int N = 4; 10 11 int board[ROW+1][COL]; 12 int block[N][N]; 13 struct { 14 int row, col; 15 } coords[N]; 16 17 int main(int argc, char** argv) { 18 19 int row, col; 20 21 // 输入数据 22 for(int i=0; i<ROW; i++) 23 for(int j=0; j<COL; j++) 24 cin >> board[i][j]; 25 for(int i=0; i<N; i++) 26 for(int j=0; j<N; j++) 27 cin >> block[i][j]; 28 cin >> col; 29 30 // 底边全放1 31 for(int j=0; j<COL; j++) 32 board[ROW][j] = 1; 33 34 // 提取小方块坐标 35 int k = 0; 36 for(int i=N-1; i>=0; i--) 37 for(int j=0; j<N; j++) 38 if(block[i][j] == 1) { 39 coords[k].row = i; 40 coords[k].col = j; 41 k++; 42 } 43 // 模拟小方块落下过程 44 row = 1; 45 col--; // 第i列表示的是数组中的i-1 46 bool checkflag; 47 for(;;) { 48 checkflag = false; 49 50 for(int i=0; i<N; i++) 51 if(board[row + coords[i].row][col + coords[i].col] == 1) { 52 checkflag = true; 53 break; 54 } 55 56 if(checkflag) 57 break; 58 59 row++; 60 } 61 row--; // 如果再往下一行会接触到1,就需要上移一行;或者是到了最底层 62 63 // 合并小方块到方格 64 for(int i=0; i<N; i++) 65 board[row + coords[i].row][col + coords[i].col] = 1; 66 67 // 输出结果 68 for(int i=0; i<ROW; i++) { 69 for(int j=0; j<COL; j++) { 70 if(j != 0) 71 cout << " "; 72 cout << board[i][j]; 73 } 74 cout << endl; 75 } 76 return 0; 77 }
以上是关于CCF 第二题的主要内容,如果未能解决你的问题,请参考以下文章