#总结# 2. 第一周周日/5h

题目集

B - Make Numbers

题目

就是给你四个数字,范围是1~9,每个字母使用一次,可以组成123位数,求出使用+、-、*之后所有可能的结果
在这里插入图片描述

思路

一开始想了一下准备列举所有情况,后来放弃了(还好
然后后来模拟的时候有一些情况也没有考虑全面,主要是不会使用这个函数
补充知识点:
next_permutation()函数实现全排列

以三个字符为例:{a,c,b}
有六个排列组合:abc,acb,bac,bca,cab,cba,并根据less-than操作符做字典顺序(lexicographical)的排序,abc的next就是acb,如果没有的话,就直接跳出循环,
需要注意的是要先使用sort排序之后再使用,否则得到的答案是从当前的序列开始的

代码

#include<bits/stdc++.h>

using namespace std;
int a[4], t;
set<int> s;
set<int>::iterator itt;
void cal2(int a, int b)
{
    t = a + b;
    if (t >= 0)
        s.insert(t);
    t = a * b;
    if (t >= 0)
        s.insert(t);
    t = a - b;
    if (t >= 0)
        s.insert(t);
}

void cal3(int a, int b, int c)
{
    t = a + b + c;
    if (t >= 0)
        s.insert(t);
    t = a + b - c;
    if (t >= 0)
        s.insert(t);
    t = a + b * c;
    if (t >= 0)
        s.insert(t);
    t = a - b + c;
    if (t >= 0)
        s.insert(t);
    t = a - b - c;
    if (t >= 0)
        s.insert(t);
    t = a - b * c;
    if (t >= 0)
        s.insert(t);
    t = a * b + c;
    if (t >= 0)
        s.insert(t);
    t = a * b - c;
    if (t >= 0)
        s.insert(t);
    t = a * b * c;
    if (t >= 0)
        s.insert(t);
}

void cal4(int a, int b, int c, int d)
{
    t = a + b + c + d;
    if (t >= 0)
        s.insert(t);
    t = a + b + c - d;
    if (t >= 0)
        s.insert(t);
    t = a + b + c * d;
    if (t >= 0)
        s.insert(t);
    t = a + b - c + d;
    if (t >= 0)
        s.insert(t);
    t = a + b - c - d;
    if (t >= 0)
        s.insert(t);
    t = a + b - c * d;
    if (t >= 0)
        s.insert(t);
    t = a + b * c + d;
    if (t >= 0)
        s.insert(t);
    t = a + b * c - d;
    if (t >= 0)
        s.insert(t);
    t = a + b * c * d;
    if (t >= 0)
        s.insert(t);
    t = a - b + c + d;
    if (t >= 0)
        s.insert(t);
    t = a - b + c - d;
    if (t >= 0)
        s.insert(t);
    t = a - b + c * d;
    if (t >= 0)
        s.insert(t);
    t = a - b - c + d;
    if (t >= 0)
        s.insert(t);
    t = a - b - c - d;
    if (t >= 0)
        s.insert(t);
    t = a - b - c * d;
    if (t >= 0)
        s.insert(t);
    t = a - b * c + d;
    if (t >= 0)
        s.insert(t);
    t = a - b * c - d;
    if (t >= 0)
        s.insert(t);
    t = a - b * c * d;
    if (t >= 0)
        s.insert(t);
    t = a * b + c + d;
    if (t >= 0)
        s.insert(t);
    t = a * b + c - d;
    if (t >= 0)
        s.insert(t);
    t = a * b + c * d;
    if (t >= 0)
        s.insert(t);
    t = a * b - c + d;
    if (t >= 0)
        s.insert(t);
    t = a * b - c - d;
    if (t >= 0)
        s.insert(t);
    t = a * b - c * d;
    if (t >= 0)
        s.insert(t);
    t = a * b * c + d;
    if (t >= 0)
        s.insert(t);
    t = a * b * c - d;
    if (t >= 0)
        s.insert(t);
    t = a * b * c * d;
    if (t >= 0)
        s.insert(t);
}

int main()
{
    cin >> a[0] >> a[1] >> a[2] >> a[3];
    sort(a, a + 4);
    do
    {
        cal2(a[0], a[1] *100 + a[2] * 10 + a[3]);
        cal2(a[0] * 10 + a[1], a[2] * 10 + a[3]);
        cal2(a[0] * 100 + a[1] * 10+a[2], a[3]);
        cal3(a[0], a[1] * 10 + a[2], a[3]);
        cal3(a[0], a[1], a[2] * 10 + a[3]);
        cal3(a[0] * 10 + a[1], a[2], a[3]);
        cal4(a[0], a[1], a[2], a[3]);
    } while (next_permutation(a, a + 4));
//    for (itt=s.begin() ;itt!=s.end();itt++)
//    {
//        cout<<*itt<<' ';
//    }
    cout << s.size() << endl;
    return 0;
}

还有一个看到的很简单的代码,值得学习

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
 
const int maxl=1e5+10;
 
int n,ans;
bool vis[maxl];
map<pair<vector<int>,int>,bool> mp;
 
inline void dfs(int stp,vector<int> a)
{
	if(mp[{a,stp}])
		return;
	mp[{a,stp}]=true;
	int l=a.size();
	if(l==1)
	{
		if(a[0]>=0 && !vis[a[0]])
		{
			vis[a[0]]=true,++ans;
			//printf("%d\n",a[0]);
		}
		return;
	}
	if(stp==1 || stp==2)  //表示*
	{
		dfs(stp+1,a);
		if(stp==1 && l==2)
			return;
		for(int i=0;i<l-1;i++)
		{
			vector<int> tmp;
			for(int j=0;j<i;j++)
				tmp.pb(a[j]);
			if(stp==1)
			{
				if(a[i+1]<10)
					tmp.pb(a[i]*10+a[i+1]);
				else
					tmp.pb(a[i]*100+a[i+1]);
			}
			else
				tmp.pb(a[i]*a[i+1]);
			for(int j=i+2;j<l;j++)
				tmp.pb(a[j]);
			dfs(stp,tmp);	
		}
	}
	if(stp==3) //+-的组合
	{
		vector<int> tmp;
		tmp.pb(a[0]+a[1]);
		for(int i=2;i<l;i++)
			tmp.pb(a[i]);
		dfs(3,tmp);
		tmp[0]=a[0]-a[1];
		dfs(3,tmp);
	}
}
 
int main()
{
	vector<int> a;
	for(int i=1;i<=4;i++)
	{
		int x;scanf("%d",&x);
		a.pb(x);
	}
	sort(a.begin(),a.end());
	do
		dfs(1,a);
	while(next_permutation(a.begin(),a.end()));
	printf("%d\n",ans);
	/*for(int i=0;i<=1e4;i++)
	if(vis[i])
		printf("%d\n",i);
	*/
	return 0;
}

E - Optimization for UltraNet

题目

在这里插入图片描述
OMG,这个题怎么这么长啊啊啊啊,孩子读不懂啊啊啊啊,呜呜呜呜哭晕(っ °Д °;)っ(对我的六级十分担忧。。)

要求:

  1. n个点,n-1条路
  2. 1有很多种情况,要选择:最小的那条路,要尽可能地大的那种
  3. 线路总和最少,最大的边要尽量小
  4. 计算总和的方法:当前边的权值为w,左侧连接的子树大小为a,右侧子树的大小为b,它的贡献就是w * a * b

思路

  1. 把边排序之后,二分枚举,看是否能组成一棵树
  2. dfs

代码

//不想写了。。先存着吧

#include <bits/stdc++.h>

#define maxx 1001
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;

//记录状态
struct node
{
    int x, y, l;
} road[maxx<<1];

bool cmp(node &a, node &b)
{
    return a.l < b.l;
}
ll  sum;
int n, m;
int fa[maxx],dis[maxx];
//连接
struct edge
{
    int x,y,l;
}e[maxx];

int find(int x)
{
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

bool Union(int x, int y)
{
    int fx = find(x);
    int fy = find(y);
    if (fx != fy)
    {
        fa[fy] = fx;
        return true;
    }
    return false;
}

void add(int x, int y, int l)
{

}

bool check(int mid, int f)
{
    for (int i = 1; i <= n; ++i)
    {
        fa[i] = i;
    }
    int cnt = 0;
    for (int i = mid; i <= m; ++i)
    {
        if (Union(road[i].x, road[i].y))
        {
            cnt++;
            if (f==1)
            {
                add(road[i].x,road[i].y,road[i].l);
                add(road[i].y,road[i].x,road[i].l);
            }
        }
    }
    return cnt == n - 1;
}

void dfs(int x,int k)
{

}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= m; ++i)
    {
        cin >> road[i].x >> road[i].y >> road[i].l;
    }
    sort(road + 1, road + 1 + m, cmp);
    int l = 1, r = m, mid, ans;
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (check(mid,0))
        {
            l = mid + 1;
            ans = mid;
        }
        else
            r = mid - 1;
    }
    check(ans,1);
    ll res=0;
    for (int i = 1; i <= n; ++i)
    {
        dis[i] = inf;
        dfs(i,-1);
        res+=sum;
        sum=0;
    }
    return 0;
}
/*
 *
 5 7
 1 2 6
 1 4 12
 1 3 10
 2 4 8
 2 5 3
 3 4 4
 4 5 2
 */

G - August

题目

给定ab,求下面函数围成的面积
在这里插入图片描述
在这里插入图片描述

思路

一个圆+两个长方形(arcsin,arccos是关于(a,-b)对称的)

J - Goodbye**

题目

游戏规则:
两个人轮流选择一个数字然后claim it(一开始看题的时候,布吉岛claim是什么意思),两人人轮流选择上一个人选的数字的真因数(In the next rounds, player should choose one positive proper divisor of the number claimed in the previous round.),最后无法作出选择的那个人赢得比赛
现在,要让Chino赢而且选择尽可能大的数字,要告诉他第一轮应该选择什么数字
▶ claim
获得、赢得 She has finally claimed a place on the team.

思路

倒推一下:
Chino win→上一个人选择的是质数→Chino的数字是由质数组成的,下一个人只能选质数
(谁先拿到质数谁就输了)

代码

#include <iostream>

using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        int sum = 0;
        int ans[100010];

        for (int i = n / 2 + 1; i >= 2; i--)
        {
            if (n % i == 0)
            {
                sum++;
                ans[sum] = i;
                n = i;//替换n
            }
        }
        if (sum == 0)
            cout << 0 << endl;
        if (sum == 1)
            cout << "-1" << endl;
        if (sum >= 2)
            cout << ans[sum - 1] << endl;
    }
    return 0;
}
<think>好的,我现在需要解决用户遇到的Ubuntu apt update时出现的“Release file is not valid yet”错误。根据用户提供的引用信息,我需要先分析问题原因,再提出解决方案。 首先,用户提到错误信息显示时间无效,比如引用[1]中的错误信息提到“invalid for another 13h 54min 24s”,这说明系统时间和源服务器的时间不同步。根据引用[5],用户执行date命令显示的时间是UTC时间2022年1月13日,而源服务器的时间可能更晚,导致系统认为证书尚未生效。因此,时间不同步是主要原因之一。 接下来,用户可能使用的是内网源,如引用[2]所述,内网镜像源可能存在同步延迟。如果内网镜像没有及时同步官方源的元数据,就会导致本地系统无法获取有效的Release文件。 解决方法方面,首先需要检查系统时间是否正确。可以通过date命令查看,如果发现时间偏差,使用ntpdate或timedatectl命令同步网络时间。例如,安装ntpdate后运行sudo ntpdate ntp.ubuntu.com,然后再次尝试更新。 如果时间正确,问题可能出在内网源的同步上。用户需要联系内网源的管理员,确认镜像是否及时同步,或者临时切换回官方源进行测试。此外,清除apt缓存也是一个步骤,使用sudo apt clean和sudo rm -rf /var/lib/apt/lists/*,再执行sudo apt update。 另外,引用[3]和[4]提到社区中类似的解决方案,比如检查时区设置、确保NTP服务正常运行。如果用户是在Docker容器中遇到此问题,可能需要检查宿主机的系统时间,或者重建容器。 总结步骤应为:检查时间→同步时间→更换源→清除缓存。同时需要根据用户的具体环境调整,比如内网情况下可能需要手动同步时间或联系管理员处理镜像源的问题。</think>### 分步解决方案 Ubuntu执行`apt update`时出现`Release file is not valid yet`错误,通常由**系统时间与软件源服务器时间不同步**或**内网镜像源未及时同步**导致。以下是具体解决步骤: --- #### **1. 检查并同步系统时间** 系统时间错误是此问题的常见原因。 - **查看当前时间**: ```bash date ``` 若时间与真实时间偏差较大(如相差几小时甚至几年),需同步时间[^1][^5]。 - **同步网络时间**: - 安装时间同步工具(若未安装): ```bash sudo apt install ntpdate ``` - 手动同步时间: ```bash sudo ntpdate ntp.ubuntu.com # 使用Ubuntu官方时间服务器 ``` - 或使用`timedatectl`(适用于systemd系统): ```bash sudo timedatectl set-ntp on # 启用自动时间同步 ``` --- #### **2. 检查软件源状态** 若时间正确但问题仍存在,可能是**软件源未及时同步**(尤其内网镜像源)。 - **临时切换官方源测试**: 编辑源列表文件: ```bash sudo nano /etc/apt/sources.list ``` 注释内网源,替换为官方源(示例为Ubuntu 20.04): ``` deb http://archive.ubuntu.com/ubuntu/ focal main restricted deb http://security.ubuntu.com/ubuntu/ focal-security main restricted ``` 更新并验证: ```bash sudo apt clean && sudo apt update ``` 若问题消失,说明内网镜像源需更新[^2]。 - **联系内网源管理员**: 若必须使用内网源,需确保镜像与官方源保持同步频率。 --- #### **3. 清除APT缓存** 过时的缓存可能导致时间校验失败: ```bash sudo apt clean # 清理已下载的包文件 sudo rm -rf /var/lib/apt/lists/* # 删除元数据缓存 sudo apt update # 重新生成缓存 ``` --- #### **4. 特殊情况处理** - **Docker容器内报错**: 检查宿主机时间是否准确,或重建容器[^4]。 - **硬件时钟问题**: 若重启后时间重置,检查主板电池或硬件时钟设置: ```bash sudo hwclock --show # 查看硬件时钟时间 ``` --- ### 总结流程图 ``` 系统时间错误? → 同步时间 → 成功 → 问题解决 ↓ 否 ↓ 内网源未同步? → 切换官方源测试 → 成功 → 更新内网镜像 ↓ 否 ↓ 清除APT缓存 → 问题解决 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值