算法笔记 + 上机实战

这篇博客介绍了C/C++快速入门,包括基本数据类型、数组操作和位运算符。接着深入讨论了算法笔记,解决Shortest Distance问题,提供了一种避免暴力遍历的解决方案,并给出了样例代码。此外,还讲解了如何根据输入日期计算星期的Day of Week问题,同样给出了C++实现。最后预告了算法初步的进一步学习内容。
摘要由CSDN通过智能技术生成

C/C++快速入门

基本数据类型

  • 位运算符
运算符含义语法效果
<<左移a << x整数 a 按二进制位左移x位
>>右移a >> x整数 a 按二进制位右移x位
&位与a & b整数 a 和 b 按二进制对齐,按位进行与运算(除了11得1,其他均为0)
|位或a | b整数 a 和 b 按二进制对齐,按位进行或运算(除了00得0,其他均为1)
^位异或a ^ b整数 a 和 b 按二进制对齐,按位进行异或运算(相同为0,不同为1)
~位取反~ a整数 a 的二进制的每一位进行0变1,1变0的操作

数组

  • 如果数组大小约106级别,则需要定义在主函数外面——栈大小限制

  • memset(数组名,值,sizeof(数组名)); 值可使用0,-1,该函数在string.h中

  • sscanf 与 sprintf

    int n;
    double db;
    char str[100];
    sscanf(str, "%d%lf", &n, &db);//将字符数组中str中的内容以"%d%lf"的形式写到n和db中,从左至右
    sprintf(str, "%d", n);//把n以"%d"的形式写到str字符数组中,从右至左
    

入门篇(1)——入门模拟

算法笔记

问题E: Shortest Distance

题目描述
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.
输入
Each input file contains one test case. For each case, the first line contains an integer N (in [3, 105]), followed by N integer distances D1 D2 … DN, where Di is the distance between the i-th and the (i+1)-st exits, and DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (<=104), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 107.
输出
For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.
样例输入
5 1 2 4 14 9
3
1 3
2 5
4 1
样例输出
3
10
7

此题有运行时间限制,所以不能用暴力遍历的方法。
我们肯定要开一个数组来存储相邻点之间的距离, 可以利用这个数组(减少空间占用)表示每个点到第一个点之间的距离。
因为两点之间的路径只有左右两个方向,因此可以分别计算出 left 和 right 输出二者的小者即可,或者若其中一个小于总和sum的一半则即可输出。

代码实现-C++

#include <iostream>
#include <vector>//动态数组,减少空间占用
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<int> distance(n+1);
    int sum = 0, special;//special 存储最后一个点距离第一个点的距离
    for(int i=1; i<=n; ++i)
    {
        cin >> distance[i];
        if(i == n)
            special = distance[i];
        sum += distance[i];
        distance[i] = sum - distance[i];//distance[i]表示i到1的距离
    }
    int m;
    cin >> m;
    while(m--)
    {
        int a, b;
        cin >> a >> b;
        if(a > b)//保持a在b前面
        {
            int t = a;
            a = b;
            b = t;
        }
        //左右路径长度
        int left = distance[b] - distance[a];
        int right = distance[n] - distance[b] + distance[a] + special;
        cout << (left>right ? right:left) << endl;
    }
    return 0;
}

问题B: Day of Week

题目描述
We now use the Gregorian style of dating in Russia. The leap years are years with number divisible by 4 but not divisible by 100, or divisible by 400.
For example, years 2004, 2180 and 2400 are leap. Years 2004, 2181 and 2300 are not leap.
Your task is to write a program which will compute the day of week corresponding to a given date in the nearest past or in the future using today’s agreement about dating.
输入
There is one single line contains the day number d, month name M and year number y(1000≤y≤3000). The month name is the corresponding English name starting from the capital letter.
输出
Output a single line with the English name of the day of week corresponding to the date, starting from the capital letter. All other letters must be in lower case.
样例输入
21 December 2012
5 January 2013
样例输出
Friday
Saturday

蔡勒公式学习
计算任何一日是星期几

代码实现-C++

#include <iostream>
#include <cstring>
#include <string>

using namespace std;
string weekday[7]{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

bool isLeap(int year)
{
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

int Alter(string month)
{
    int m;
    switch (month[0])
    {
    case 'F':
        m = 14;
        break;
    case 'S':
        m = 9;
        break;
    case 'O':
        m = 10;
        break;
    case 'N':
        m = 11;
        break;
    case 'D':
        m = 12;
        break;
    case 'J':
        if (month[1] == 'a')
            m = 13;
        else if (month[2] == 'n')
            m = 6;
        else if (month[2] == 'l')
            m = 7;
        break;
    case 'M':
        if (month[2] == 'r')
            m = 3;
        else
            m = 5;
        break;
    case 'A':
        if (month[2] == 'r')
            m = 4;
        else
            m = 8;
        break;
    }
    return m;
}

int main()
{
    int day, year;
    string month;
    while (cin >> day >> month >> year)
    {
        int y, c, m, d, w;
        y = c = m = d = w = 0;
        m = Alter(month);
        if (m > 12)
        {
            c = (year - 1) / 100;
            y = (year - 1) % 100;
        }
        else
        {
            c = year / 100;
            y = year % 100;
        }
        d = day;
        w = y + y / 4 + c / 4 - 2 * c + 26 * (m + 1) / 10 + d - 1;
        int nowDay = 0;
        while (w < 0)//处理负数的取余
            w += 7;
        nowDay = w % 7;
        cout << weekday[nowDay] << endl;
    }
    return 0;
}

上级训练实战指南

入门篇(2)——算法初步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值