大一蓝桥杯三

一:四平方和

四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开
例如,输入:
5
则程序应该输出:
0 0 1 2
再例如,输入:
12
则程序应该输出:
0 2 2 2
再例如,输入:
773535
则程序应该输出:
1 1 267 838
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
int N;
map<int, int>cache;
int main() {
    scanf("%d", &N);
    for (int c = 0; c * c <= N/2; ++c) {
        for (int d = c; c * c + d * d <= N; ++d) {
            if(cache.find(c*c+d*d)==cache.end())
            cache[c * c + d * d] = c;
        }
    }
    for (int a = 0; a * a <= N / 4; ++a) {
        for (int b = a; a * a + b * b <= N / 2; ++b) {
            if (cache.find(N - a * a + b * b) != cache.end())
            {
                int c = cache[N - a * a - b * b];
                int d = int(sqrt(N - a * a - b * b - c * c));
                printf("%d %d %d %d %d\n", a, b, c, d);
                return 0;
            }
        }
    }
}

当然直接四重循环也可以;
设计:STL中Map集合类

方格分割

#include<stdio.h>
struct node
{
    int x;
   int y;
};
int ans = 0;
int x[4] = { 0,0,-1,1 };
int y[4] = { -1,1,0,0 };
int book[10][10] = { 0 };
void dfs(node p1, node p2)
{
    if (p1.x == 0 || p1.x == 6 || p1.y == 0 || p1.y == 6)
    {
        ans++;
        return;
    }
    node pp1, pp2;
    for (int i = 0; i < 4; i++)
    {
        pp1.x = p1.x + x[i];
        pp1.y = p1.y + y[i];
        pp2.x = p2.x - x[i];
        pp2.y = p2.y - y[i];
        if (book[pp1.x][pp1.y] != 1)
        {
            book[pp1.x][pp1.y] = 1;
            book[pp2.x][pp2.y] = 1;
            dfs(pp1, pp2);
            book[pp1.x][pp1.y] = 0;
            book[pp2.x][pp2.y] = 0;
        }
    }
}
int main()
{
    node p;
    p.x = 3;
    p.y = 3;
    book[p.x][p.y] = 1;
    dfs(p, p);
    printf("%d\n", ans / 4);
    return 0;
}

日期问题

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
  比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
  给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入格式
  一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输出格式
  输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入
02/03/04
样例输出
2002-03-04
2004-02-03
2004-03-02

代码:

#include<iostream>
#include<sstream>
#include <set>
using namespace std;
bool isleap(int year) {//用来判断是否是闰年
    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
void i2s(int i, string &s) {//转化为字符串输出的方法
    stringstream ss;
    ss << i;
    ss >> s;
}
string f(int a, int b, int c) {//判断年月日是否符合规定
    if (a >= 0 && a <= 59)a += 2000;
    else if (a >= 60 && a <= 99)a += 1900;
    else return "";
    if (b < 1 || b>12)return "";
    if (c < 1 || c>31)return "";
    bool _isleap = isleap(a);
    switch (b) {//日期校验
    case 2:if (_isleap && c > 29)return "";
        if (_isleap && c > 28)return "";
        break;
    case 4:if (c > 30)return "";
        break;
    case 6:if (c > 30)return "";
        break;
    case 9:if (c > 30)return "";
        break;
    case 11:if (c > 30)return "";
        break;
    default:
        break;
    }
    //转化为字符串
    string _a, _b, _c;
    i2s(a, _a);
    i2s(b, _b);
    i2s(c, _c);
    if (_b.length() == 1)_b = '0' + _b;
    if (_c.length() == 1)_c = '0' + _c;
    return _a + "-" + _b + "_" + _c;
}
int main() {
    string in;
    cin >> in;
    int a = 0, b = 0, c = 0;
    a = (in[0] - '0') * 10 + (in[1] - '0');
    b = (in[3] - '0') * 10 + (in[4] - '0');
    c = (in[6] - '0') * 10 + (in[7] - '0');
    string case1 = f(a, b, c);
    string case2 = f(c, a, b);
    string case3 = f(c, b, a);
    set<string>ans;//创建集合,插入符合的数据
    if (case1 != "")ans.insert(case1);
    if (case2 != "")ans.insert(case2);
    if (case3 != "")ans.insert(case3);
    //迭代输出
    for (set<string>::iterator iter = ans.begin(); iter != ans.end(); iter++) {
        cout << *iter << endl;
    }
    return 0;
}

STL-SETc++中的集合set

分巧克力

实力有限,不会。
看完就能会。
使用了二分法
直接参考:分巧克力解析
注意:int m=(l+r)>>1,相当于/2取整。

K倍区间

自己的想法时超时的。。。。。。
请参考:https://blog.csdn.net/qq_34594236/article/details/70845223

发布了68 篇原创文章 · 获赞 133 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_45822638/article/details/104846900