在线OJ(一)

一、奇数位上都是奇数或者偶数位上都是偶数

给定一个长度不小于2的数组arr。 写一个函数调整arr,使arr中要么所有的偶数位上都是偶数,要么所有的奇数位上都是奇数上。 要求:如果数组长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1),下标0,2,4,6…算作偶数位,下标1,3,5,7…算作奇数位,例如[1,2,3,4]调整为[2,1,4,3]即可.

对于数组arr而言,偶数个数和奇数个数相同当然为理想情况了,若是偶数个数大于(小于)奇数个数则需要考虑保证偶数(奇数)位上满足条件

  • 为了让偶数(奇数)位上的元素满足要求以尾元素为操作空间,从头到尾将元素奇放入尾部进行奇偶性判断然后放入相应位置,直到某一要求达到
class Solution {
public:
    /**
     *  奇数位上都是奇数或者偶数位上都是偶数
     *  输入:数组arr,长度大于2
     *  len:arr的长度
     *  将arr调整成奇数位上都是奇数或者偶数位上都是偶数
     */
    void oddInOddEvenInEven(vector<int>& arr, int len) {
        int even = 0;
        int odd = 1;
        int& tail = arr[len - 1];
        
        while(even < len && odd < len)
        {
            //tail = arr[len - 1];//出错
            if((tail & 1) == 0)//出错
            {
                swap(tail, arr[even]);
                even += 2;
            }
            else{
                swap(tail, arr[odd]);
                odd += 2;
            }
        }
    }
};

说上两个坑,一个就是[]&的优先级问题,在这我先没有带括号,结果导致判断错误,这种错误很难发现,以后的关于&运算不管难不难记得一定要带上括号;另一个就是设定tail时,如果使用tail = arr[len - 1];tail是arr[len - 1]的一份拷贝,这样只会是一种单向赋值即在之后的swap中只会给arr[even]arr[odd]完成赋值,而实际的arr[len - 1]却并没有完成交换数值的愿望,所以就设定tailarr[len - 1]的引用

二、淘宝网店

NowCoder在淘宝上开了一家网店。他发现在月份为素数的时候,当月每天能赚1元;否则每天能赚2元。现在给你一段时间区间,请你帮他计算总收益有多少

输入包含多组数据。
每组数据包含两个日期from和to (2000-01-01 ≤ from ≤ to ≤ 2999-12-31)。
日期用三个正整数表示,用空格隔开:year month day
2000 1 1 2000 1 31
2000 2 1 2000 2 29

对应每一组数据,输出在给定的日期范围(包含开始和结束日期)内能赚多少钱
62
29

  • 对于输入的每组日期值先看其是不是同年,若同年再看是不是同月。对于同年不同月的要着重考虑起始月和终止月,对于不同年的要着重考虑起始年和终止年,另外还要考虑到是否闰年,是否素数月份的问题
#include <iostream>
#include <vector>
using namespace std;

int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int PrimesMonth[5] = {2, 3, 5, 7, 11};

bool IsLeapYear(int year)
{
    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
        return true;
    
    return false;
}
bool IsPrimesMonth(int month)
{
    for(int i = 0;i < 5;i++)
    {
        if(month == PrimesMonth[i])
            return true;
    }
    return false;
}

int main()
{
    int yearf,monthf,dayf,yeart,montht,dayt;
    vector<int> money;
    
    while(cin >> yearf >> monthf >> dayf >> yeart >> montht >> dayt)
    {
        int income = 0;
        
        //同年
        if(yearf == yeart)
        {
            int month_money[13] = {0, 62, 28, 31, 60, 31, 60, 31, 62, 60, 62, 30, 62 };
            if(IsLeapYear(yearf))
            {
                month_money[2] += 1;
            }
            //同月
            if(monthf == montht)
            {
                //素数月
                if(IsPrimesMonth(monthf))
                {
                    int days = dayt - dayf + 1;
                    income += days;
                }
                else//非素数月
                {
                    int days = dayt - dayf + 1;
                    income += days * 2;
                }
            }
            else//不同月
            {
                //起始月
                if(IsPrimesMonth(monthf))
                {
                    int days = month[monthf] - dayf + 1;
                    income += days;
                }
                else//非素数月
                {
                    int days = month[monthf] - dayf + 1;
                    income += days * 2;
                }
                
                for(int m = monthf + 1; m < montht; m++)
                {
                    income += month_money[m];
                }
                
                //终止月
                if(IsPrimesMonth(montht))
                {
                    int days = dayt - 1 + 1;
                    income += days;
                }
                else//非素数月
                {
                    int days = dayt - 1 + 1;
                    income += days * 2;
                }
            }
            money.push_back(income);
        }
        else//不同年
        {
            //第一年
            int fmonth_money[13] = {0, 62, 28, 31, 60, 31, 60, 31, 62, 60, 62, 30, 62 };
            if(IsLeapYear(yearf))
            {
                fmonth_money[2] += 1;
            }
            if(IsPrimesMonth(monthf))
            {
                    int days  = dayf - 1 + 1;
                    income += days;
            }
            else//非素数月
            {
                    int days = dayf - 1 + 1;
                    income += days * 2;
            }
            for(int m = monthf + 1; m < 13; m++)
            {
                    income += fmonth_money[m];
            }
            
            for(int y = yearf + 1;y < yeart; y++)
            {
                int month_money[13] = {0, 62, 28, 31, 60, 31, 60, 31, 62, 60, 62, 30, 62 };
                if(IsLeapYear(y))
                {
                    month_money[2] += 1;
                }
                
                for(int m = 1; m < 13; m++)
                {
                    income += month_money[m];
                }
                
            }
            
            //最后一年
            int Lmonth_money[13] = {0, 62, 28, 31, 60, 31, 60, 31, 62, 60, 62, 30, 62 };
            if(IsLeapYear(yeart))
            {
                Lmonth_money[2] += 1;
            }
            for(int m = 1; m < montht; m++)
            {
                    income += Lmonth_money[m];
            }
            if(IsPrimesMonth(montht))
            {
                    int days  = dayt - 1 + 1;
                    income += days;
            }
            else//非素数月
            {
                    int days = dayt - 1 + 1;
                    income += days * 2;
            }
           money.push_back(income);
        }
    }
    for(int i = 0;i < money.size();i++)
    {
        cout << money[i] << endl;;
    }
    return 0;
}

在牛客网上跑了下代码,居然卡在98.8%,然后一看是输入2000 1 1 2999 12 31出错了,后来想想都笑了,谁家生意能延续上一千年的,就算延续了一千年难道还能一直做每天2块1块的生意吗,所以从现实来说这个代码还是可以的(ps:自我安慰)后来找了下100%的解决方法

#include <iostream>
// 每月天数,不考虑闰年,从 0 开始
inline int day_of_month(int m) {
	const static int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	return days[m];
}
// 判断是否是闰年
inline bool leap_year(int y) {
	if (y % 4 == 0 && y % 100 != 0) {
		return true;
	}
	if (y % 400 == 0) {
		return true;
	}
	return false;
}
// 一年的收益,不考虑闰年
inline int profit_of_year() {
	return 2 * 31
		+ 1 * 28
		+ 1 * 31
		+ 2 * 30
		+ 1 * 31
		+ 2 * 30
		+ 1 * 31
		+ 2 * 31
		+ 2 * 30
		+ 2 * 31
		+ 1 * 30
		+ 2 * 31;
}
// 判断月份是否是素数,从 0 开始
inline bool prime(int m) {
	const static bool p[] = { false, true, true, false, true, false, true, false, false,
		false, true, false };
	return p[m];
}
int main() {
	int year1, month1, day1, year2, month2, day2;
	while (std::cin >> year1 >> month1 >> day1 >> year2 >> month2 >> day2)
	{
		int profit = 0;
		int year = year1;
		// 计算完整年份的收益
		for (int y = year1; y <= year2 - 1; ++y)
		{
			profit += profit_of_year();
			if (leap_year(y))
			{
				profit += 1;
			}
		}
		// 减去多计算的 year1 从 1月(0) 到 month1 的收益
		for (int m = 0; m < month1; ++m)
		{
			int days;
			if (m == month1 - 1) {
				// 这个月不完整
				days = day1 - 1;
			}
			else {
				days = day_of_month(m);
				if (m == 1 && leap_year(year1))
				{
					days += 1;
				}
			}
			int profit_of_month = days * (prime(m) ? 1 : 2);
			profit -= profit_of_month;
		}
		// 加上少计算的 year2 从 1月(0) 到 month2 的收益
		for (int m = 0; m < month2; ++m)
		{
			int days;
			if (m == month2 - 1) {
				// 这个月不完整
				days = day2;
			}
			else {
				days = day_of_month(m);
				if (m == 1 && leap_year(year2))
				{
					days += 1;
				}
			}
			int profit_of_month = days * (prime(m) ? 1 : 2);
			profit += profit_of_month;
		}
		std::cout << profit << '\n';
	}

	system("pause");
	return 0;
}

版权声明:本文为kuisi95原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。