• 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 没做出来,生气Alt text
    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 }

    公共钥匙盒

    1. 钥匙盒用数组表示,存储钥匙ID,没有则为-1
    2. 老师的时间、操作不同,对钥匙盒的改变也不同,需要创建坐标轴的元素改变结点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 }
  • 相关阅读:
    作业九 主成分分析
    作业八 特征选择
    作业七 逻辑回归应用
    作业六 逻辑回归
    作业五 线性回归算法
    第十四次作业:手写数字识别-小数据集
    第十三次作业:深度学习-卷积
    第七次作业:7.逻辑回归实践
    第十二次作业:垃圾邮件分类2
    第十一次作业:朴素贝叶斯-垃圾邮件分类
  • 原文地址:https://www.cnblogs.com/twomeng/p/9509478.html
Copyright © 2020-2023  润新知