1.小数第n位
问题描述
我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。
如果我们把有限小数的末尾加上无限多个0,它们就有了统一的形式。
本题的任务是:在上面的约定下,求整数除法小数点后的第n位开始的3位数。
输入说明
一行,三个整数:a b n,用空格分开。a是被除数,b是除数,n是所求的小数后位置(0<a,b,n<1000000000)
输出说明
一行,3位数字,表示:a除以b,小数后第n位开始的3位数字。
比如输入:
1 8 3
则输出
500
个人总结
1.大数除法,利用快速幂方法
2.计算10^k,巧妙利用二进制拆分:
- 如果二进制当前位是1,就累乘到结果里
- 底数翻倍:10^1 -> 10^2 -> 10^4 -> 10^8
- 处理下一位二进制
cpp
#include <iostream>
using namespace std;
//快速幂取模
long long power_mod(long long a,long long k,long long b){ //(a*(10^k))%b
long long res=a%b;
long long base=10; //底数设为10
while(k>0){//计算10^k,利用k的二进制
if(k%2==1) res=(res*base)%b;
base=(base*base)%b;
k/=2;
}
return res;
}
int main() {
long long a, b, n;
cin >> a >> b >> n;
long long remain=power_mod(a,n-1,b);
//从那个余数开始,模拟 3 次除法过程
for(int i=0;i<3;i++){
remain*=10;
cout<<remain/b; //输出当前的商
remain%=b; //更新余数
}
cout<<endl;
return 0;
}
2.丑数
问题描述
对于一给定的素数集合 S = {p1, p2, ..., pK}, 来考虑那些质因数全部属于S 的数的集合。
这个集合包括,p1, p1p2(即p1乘以p2), p1p3, 和 p1p2p3 (还有其它很多)。
这是个对于一个集合S的丑数集合。注意:我们不认为1 是一个丑数。
你的工作是对于输入的集合S去寻找集合中的第N个丑数。
说明:结果不超过32位整数能表示的范围
比如:S={2, 3, 5, 7}
则前15个丑数为:
2,3,4,5,6,7,8,9,10,12,14,15,16,18,20
输入说明
第 1 行: 2个被空格分开的整数:K 和 N , 1<= K<=100 , 1<= N<=100,000.
第 2 行: K 个被空格分开的整数,即集合S的元素
输出说明
单独的一行,即第N个丑数。
个人总结
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int k,n;
cin>>k>>n;
vector<int> s(k);
for(int i=0;i<k;i++) cin>>s[i];
vector<long long> uglies;
uglies.push_back(1); //为方便计算,uglies[i]表示第i个丑数
vector <int> ptr(k,0);//代表该质数接下来要与哪一个丑数相乘
while(uglies.size()<=n){
long long min=LLONG_MAX;
//寻找当前所有候选中的最小值
for(int i=0;i<k;i++){
long long cur=(long long)s[i]*uglies[ptr[i]];
if(cur<min)
min=cur;
}
uglies.push_back(min);
//更新所有指向该最小值的指针,实现去重
for(int i=0;i<k;i++){
if((long long)s[i]*uglies[ptr[i]]==min) ptr[i]++;
}
}
cout<<uglies[n]<<endl;
return 0;
}
3.阶乘末尾
问题描述
给定n和len,输出n!末尾len位。
输入说明
一行,两个正整数n和len。
n<=30, len<=10。
输出说明
一行,一个字符串,表示答案。长度不足用前置零补全。
个人总结
n=30时会溢出 n<=20不会溢出
题目要求只输出末尾的 len 位,等同于对 10^len 取模
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, len;
if (!(cin >> n >> len)) return 0;
// 计算模数, len=3, mod=1000
long long mod = 1;
for (int i = 0; i < len; i++) {
mod *= 10;
}
long long fact = 1;
for (int i = 2; i <= n; i++) {
// 每一步都取模,防止溢出
fact = (fact * i) % mod;
}
// 使用 %0*lld 格式化输出,* 对应 len,表示宽度,不足补 0
printf("%0*lld\n", len, fact);
return 0;
}
大数的阶乘:模拟竖式乘法
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> res;
res.push_back(1); // 初始结果为 1
for (int i = 2; i <= n; i++) {
int carry = 0; // 进位
for (int j = 0; j < res.size(); j++) {
int prod = res[j] * i + carry;
res[j] = prod % 10; // 存当前位
carry = prod / 10; // 算进位
}
// 如果最后还有进位,不断向数组后方添加
while (carry) {
res.push_back(carry % 10);
carry /= 10;
}
}
// 数组里是逆序存的(res[0]是个位),所以要倒序输出
cout << n << "! = ";
for (int i = res.size() - 1; i >= 0; i--) {
cout << res[i];
}
cout << endl;
return 0;
}
英语翻译
Pretrained models have become a dominant paradigm in modern artificial intelligence. These models are first trained on large-scale datasets to learn general representations and then fine-tuned on specific downstream tasks. This approach significantly reduces the need for labeled data and improves model performance. In natural language processing, models like BERT and GPT are pre-trained using self-supervised learning objectives. Fine-tuning allows these models to adapt to tasks such as text classification, sentiment analysis, and question answering. Transfer learning plays a crucial role in this process by leveraging knowledge from one domain to another. Despite their effectiveness, pretrained models require substantial computational resources, raising concerns about efficiency and environmental impact.
预训练模型已经是人工智能领域的一个主要的模型。这些模型先在大规模数据上训练,学习基本属性,然后在特定的下游任务中微调。这个方法极大的减少了标注数据的需要并且提高了模型的性能。在自然语言处理中,BERT和GPT模型用自监督学习目标来预训练。微调让这些模型适应一些任务,比如文本分类,情感分析和问答。转移学习在这个过程中有重要作用,它将知识从一个领域转移到另一个领域。虽然他们效率很高,但是预训练模型需要大量的计算资源,产生了关于效率和环境影响的问题。