CCF-CSP_201712(第12次)

本文详细探讨了2017年12月的CCF CSP考试中涉及的五大主题:如何找到数列的最小差值、解决策略类游戏问题、理解和使用Cron任务调度、规划最优化的行车路线以及商业路线的优化策略。通过对这些内容的深入分析,为读者提供了全面的解题思路和技术要点。
摘要由CSDN通过智能技术生成

1.最小差值

#include <iostream>
#include <algorithm>
#define MAXN 1005
#define INF 0x3f3f3f3f
using namespace std;

int a[MAXN];
int main(){
   
    int n, ans = INF;
    
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
        scanf("%d", &a[i]);
    sort(a, a + n);
    for(int i = 1; i < n; ++i)
        ans = min(ans, a[i] - a[i-1]);
    
    printf("%d\n", ans);
    return 0;
}
5 
1 5 4 8 20

1
5 
9 3 6 1 3

0

2.游戏

//模拟
#include<iostream>
#include<queue>
using namespace std;
 
int main()
{
   
    int n, k;
    queue<int> q;
    
    cin >> n >> k;
    for(int i = 1;i <= n; ++i)
        q.push(i);//store n numbers
    
    int top, no = 0;
    while(!q.empty()){
   
        top = q.front();
        q.pop();
        no++;
        if(no%k != 0 && (no%10) != k)
            q.push(top); //与n有关
    }
    cout << top << endl;;
    
    return 0;
}
5 2

3
7 3

4

3.Crontab

//思维
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
 
typedef long long LL;
int firstYear, lastYear;    // 开始与结束的年份
int range[5] = {
    60, 24, 31, 12, 7 };
int days[13] = {
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
string week[] = {
    "sun", "mon", "tue", "wed", "thu", "fri", "sat" },
mon[] = {
    "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" };
map<string, int> mp;    // 保存各个英文缩写对应的值
vector<pair<LL, int> > ans;    // ans存放结果的 "时间,id" 对
 
// 如果是字母开头,一定是英文缩写,直接返回mp中对应的值;否则就是数字,按位累加即可
int strToI(string &str)
{
   
    if (isalpha(str[0]))
        return mp[str];
    int num = 0;
    for (int i = 0; i != str.size(); ++i)
        num = num * 10 + str[i] - '0';
    return num;
}
 
void dealMinus(set<LL> &tmp, string &str)
{
   
    for (int i = 0; i != str.size(); ++i)
        str[i] = tolower(str[i]);    // 不区分大小写
    size_t tp = str.find('-');
    if (tp == string::npos)
        tmp.insert(strToI(str));
    else{
   
        string left = str.substr(0, tp), right = str.substr(tp + 1);
        int l = strToI(left), r = strToI(right);
        for (int i = l; i <= r; ++i)
            tmp.insert(i);
    }
}
 
// 先分析s是否为"*",再分析',',最后分析'-'
void findValue(set<LL> &tmp, string &s, int j)
{
   
    if (s == "*"){
   
        for (int i = 0; i != range[j]; ++i)
            if (j == 2 || j == 3)    // 日期和月份是1开头的
                tmp.insert(i + 1);
            else
                tmp.insert(i);
        return;
    }
    s += ',';
    size_t pos = 0, next = s.find(',');
    string str;
    while (next != string::npos){
   
        str = s.substr(pos, next - pos);
        dealMinus(tmp, str);
        pos = next + 1;
        next = s.find(',', pos);
    }
}
 
// 分析y年m月d日是星期几,顺便排除一下不合法的日期比如11月31日
int getDay(int year, int month, int day)
{
   
    days[2] = 28;
    if (year % 4 == 0)
        days[2] = 29;
    if (day > days[month])    // 该日期不存在
        return -1;
 
    int sum = 4, q = year - 1970;
    sum += q / 4 * 5 + q % 4;    // 每隔四年,sum应该+5
    if (q % 4 == 3)    // 这时说明 year-1 为闰年
        ++sum;
    for (int i = 1; i != month; ++i)
        sum += days[i];
    sum += day - 1;
    return sum % 7;
}
 
// v[0] ~ v[3]不进行判断,只把tmp与pre中的内容组合起来,所有的判断放在v[4]中
void fillVector(vector<vector<LL> > &v, vector<LL> &tmp, int j, LL mul)
{
   
    if (j == 0)
        v[j] = tmp;
    else{
   
        vector<LL> &pre = v[j - 1];
        if (j != 4)
            for (int k = 0; k != tmp.size(); ++k)
                for (int l = 0; l != pre.size(); ++l)
                    v[j].push_back(tmp[k] * mul + pre[l]);
 
        else{
   
            int judge[7] = {
    0 };    // 用于判断一周中的每一天是否能够执行该命令
            for (int k = 0; k != tmp.size(); ++k)
                judge[tmp[k]] = 1;
            for (int l = 0; l != pre.size(); ++l){
   
                int month = pre[l] / 1000000, day = pre[l] / 10000 % 100;
                for (int year = firstYear; year <= lastYear; ++year){
   
                    int dow = getDay(year, month, day);
                    if (dow != -1 && judge[dow
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值