东华复试OJ二刷复盘13

进阶19:有n个人排队到r个水龙头去打水,他们装满水桶的时间t1、t2...........tn为整数且各不相等,应如何安排他们的打水顺序才能使他们总共花费的时间最少?第一行n,r 第二行为n个人打水所用的时间Ti 。

  • 写了一小时。题都读不懂,实际是求周转时间之和,即每个任务的提交时间到完成时间之和。
  • for(int i=0;i<UseR.size();i++){
    if(UseR[i]==-1){
    for(int j=0;j<times.size();j++){
    if(times[j].GetR==0&&times[j].finished==0){
    times[j].GetR=1;
    UseR[i]=j;
    break; //没加break导致死循环。找到一个未完成的任务,拥有资源后退出寻找,否则会继续寻找下一个未完成的任务覆盖资源使用权。
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

struct NeedT{
	int CounT=0;
	int need=0;
	int finished=0;
	int GetR=0;//是否占据水龙头 
};

bool forSort(NeedT a,NeedT b){
	return a.need<b.need;
}

int ProcessTime(vector<NeedT> &times,vector<int> &UseR){
	//0.未完成的需求的等待时间+1
	for(auto &it:times){
		if(it.finished==0)it.CounT++;
	}
	
	//1.占据水龙头的需求全部-1,并将为0的需求释放掉
	for(int i=0;i<UseR.size();i++){
		if(UseR[i]!=-1)times[UseR[i]].need--;
		if(UseR[i]!=-1&&times[UseR[i]].need==0){
			times[UseR[i]].finished=1;
			times[UseR[i]].GetR=0;
			UseR[i]=-1;
		}
	}
	//2.检查为空的水龙头,安排需求上去
	for(int i=0;i<UseR.size();i++){
		if(UseR[i]==-1){
			for(int j=0;j<times.size();j++){
				if(times[j].GetR==0&&times[j].finished==0){
					times[j].GetR=1;
					UseR[i]=j;
					break;
				}
			}
		}
	}
}

int main(){
	int len,r;cin>>len>>r;
	vector<NeedT> times;
	for(int i=0;i<len;i++){
		NeedT temp;
		cin>>temp.need;
		times.push_back(temp);
	}
	sort(times.begin(),times.end(),forSort);
	
	vector<int> UseR(r,-1);//记录当前使用水龙头的下标 
	
	while(1){
		ProcessTime(times,UseR);
		int CanBreak=1;
		for(auto &it:times){
			if(it.finished==0)CanBreak=0;
		}
		if(CanBreak)break;
	}
	
	int ansT=0;
	for(auto it:times){
		ansT+=it.CounT;
	}
	ansT-=times.size();
	cout<<ansT;
	
	system("pause");
} 

基础121:一对兄弟分糖果,弟弟只会对糖果的价值进行二进制无进位的加法,请计算出弟弟相信他们得到糖果价值的总量是相同的,且哥哥能得到的最大的价值。若不能输出NO,若能则输出哥哥得到的最大的价值。

  • 对十进制整数做二进制无进位加法:ans = num1 ^ num2
    • 取反 ans=~num1
  • 错误1:题目要求两堆都非空,应检查 if (Big.empty() || Little.empty()) return;
  • 错误2:ans = max(ans,sumB); 这里的sumB是按照弟弟算法得到的值,而不是实际糖果值,不应该保存这个值
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int ans = 0;

int Add(int num1,int num2){
	vector<int> num1_bin;
	vector<int> num2_bin;
	while(num1>0){
		num1_bin.push_back(num1%2);
		num1/=2;
	}
	while(num2>0){
		num2_bin.push_back(num2%2);
		num2/=2;
	}
	
	int i=0,j=0;
	vector<int> addnum;
	while(i<num1_bin.size() || j<num2_bin.size()){
		int temp=0;
		if(i<num1_bin.size())temp+=num1_bin[i];
		if(j<num2_bin.size())temp+=num2_bin[j];
		addnum.push_back(temp%2);
		i++;j++;
	}
	int res=0;
	for(int i=0;i<addnum.size();i++){
		int temp = addnum[i];
		for(int j=0;j<i;j++)temp*=2;
		res+=(temp);
	}
	return res;
}

void Check(vector<int>&Big,vector<int>&Little){
	if (Big.empty() || Little.empty()) return;
	int sumB=0,sumL=0;
	for(int i=0;i<Big.size();i++){
		sumB = Add(sumB,Big[i]);
	}
	for(int i=0;i<Little.size();i++){
		sumL = Add(sumL,Little[i]);
	}
	if(sumB == sumL){
		int temp=0;
		for(auto it:Big){
			temp+=it;
		}
		ans = max(ans,temp);
	}//ans = sumB;
}

void DFS(int index,vector<int>&bags,
vector<int> Big,vector<int> Little){
	if(index==bags.size()){
		Check(Big,Little);
		return;
	}
	//分给哥哥 
	vector<int> new1Big = Big;
	new1Big.push_back(bags[index]);
	DFS(index+1,bags,new1Big,Little);
	//分给弟弟 
	vector<int> new1Little = Little;
	new1Little.push_back(bags[index]);
	DFS(index+1,bags,Big,new1Little);
}

int main(){
	int loop;cin>>loop;
	while(loop-->0){
		ans = 0;
		int len;cin>>len;
		vector<int> bags(len);
		for(int i=0;i<len;i++){
			cin>>bags[i];
		}
		vector<int> Big;
		vector<int> Little;
		DFS(0,bags,Big,Little);
		if(ans)cout<<ans<<endl;
		else cout<<"NO"<<endl;
	}
	system("pause");
}

基础122:给你一个数字 M (在1到9位之间), 找出第一个比 M大的循环数,循环数是那些不包括0这个数字的没有重复数字的整数 ,从最左边的数字开始往右边数,一直数n个数字,停在另一个不同的数字上,继续按照该规则数。每一个数字都被数了1次,并且回到了起点。

  • 错误1:countNums[n%10]++; 越界异常,找了半天,1~9的下标为0~8,长度为9,下标9越界了。
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

void CountNum(int &index,vector<int>&nums,vector<int>&Used){
	Used[index]++;
	index = (index +nums[index])%nums.size();
}

bool Check2(vector<int>&Used){
	for(auto it:Used){
		if(it!=1)return false;
	}
	return true;
}

bool Check(int n){
	vector<int> nums;
	vector<int> Used;
	vector<int> countNums(9,0);
	while(n>0){//1.不含0 
		if(n%10==0)return false;
		else{
			nums.push_back(n%10);
			Used.push_back(0);
			countNums[n%10-1]++;
			if(countNums[n%10-1]>1)return false;
			//1.1不含重复数字
		}
		n/=10;
	}
	reverse(nums.begin(),nums.end());
	//2.数数
	int index=0;
	for(int i=0;i<nums.size();i++){
		CountNum(index,nums,Used);
	}
	
	return (index ==0 && Check2(Used));
	
}

int main(){
	int n;cin>>n;
	while(1){
		n++;
		if(Check(n))break;
	}
	cout<<n;
	system("pause");
}

基础22:约瑟夫环2

  • 核心公式:pos = (pos + m - 1) % (2 * K - killed); 从pos开始数m个活人,取余 (2 * K - killed)为当前队伍人数
    • Q:pos会落到已出队的下标?
    • A:计算的pos属于排除之后的新队伍,在下标的含义上两者没有关系,不能用来访问对应位置。是从数学角度不断对新队伍数到新排除位置。
cpp 复制代码
#include <stdio.h>
#include <string.h>

int main() {
    int K;
    
    while(scanf("%d", &K) != EOF && K != 0) {
        int m = K + 1;  // 从K+1开始尝试
        
        while(1) {
            int pos = 0;      // 当前位置,从0开始(淘汰的下一个人)
            int killed = 0;   // 已淘汰的坏人数
            int possible = 1; // 这个m是否可行
            
            // 模拟:要淘汰K个坏人
            while(killed < K) {
                // 淘汰第m个有效的人
                pos = (pos + m - 1) % (2 * K - killed);
                
                // 检查淘汰的是否是好人(前K个)
                if(pos < K) {
                    possible = 0;
                    break;
                }
                
                killed++;
                // 调整位置:后面的人往前移
                // pos现在指向下一个要淘汰的人
            }
            
            if(possible) {
                printf("%d\n", m);
                break;
            }
            m++;
        }
    }
    
    return 0;
}

Overfitting is a common problem during the training of machine learning models. When a model performs extremely well on training data but poorly on test data, it is considered to suffer from overfitting. This usually occurs when the model is too complex or when the amount of training data is insufficient. To reduce overfitting, researchers have proposed various techniques such as regularization, data augmentation, and cross-validation. Regularization methods introduce penalty terms into the loss function to limit the magnitude of model parameters, thereby making the model simpler and more stable. Data augmentation increases the diversity of training data by applying operations such as rotation, cropping, or adding noise to the original data. In addition, cross-validation evaluates the generalization ability of a model by repeatedly splitting the dataset into training and validation sets. These techniques can effectively improve the performance of machine learning models in real-world applications.

  • 过拟合是机器学习模型训练中一个常见的问题。当一个模型在训练集上表现得极好,在测试集上却很差,那么可以认为它过拟合了。这通常发生在模型过于复杂或训练集的规模不够充足。为了减少过拟合,研究员提出了许多技术例如正则化、数据增强和交叉验证。正则化方法往损失函数中引入惩罚术语来限制模型参数的幅度,从而使模型更简单和更稳定。数据增强通过应用诸如旋转、裁切或往原始数据中增加噪音的操作来增加训练集的多样性。另外,交叉验证通过不断将数据集分割为训练集和验证集来评估一个模型的泛化能力。这些技术能有效的提高机器学习模型在现实应用的表现。
  • it is considered to suffer from 可被视为存在(某物)
  • cross-validation 交叉验证
  • rotation 旋转、 cropping 裁切、
相关推荐
TechPioneer_lp2 小时前
腾讯客户端开发岗位 LeetCode 高频题汇总(2026版)
算法·leetcode·面试·求职招聘·笔试·腾讯校招·leetcode高频题
夏日听雨眠2 小时前
数据结构1
数据结构·算法
雨落在了我的手上2 小时前
C语言之数据结构初见篇(7):单链表的介绍(3)
数据结构
jing-ya2 小时前
day 55 图论part7
java·数据结构·算法·图论
我爱我家8822 小时前
亚洲艺术电影节携澳门文化亮相深圳
人工智能·物联网·算法·区块链·爬山算法
Aawy1202 小时前
C++中的状态模式高级应用
开发语言·c++·算法
zyq99101_12 小时前
蓝桥杯刷题算法实战解析
数据结构·python·算法·蓝桥杯
sali-tec2 小时前
C# 基于OpenCv的视觉工作流-章39-FL特征匹配
图像处理·人工智能·opencv·算法·计算机视觉
Liu628882 小时前
C++中的状态模式
开发语言·c++·算法