1049.1的个数

#include<iostream>
#include<vector>
using namespace std;
int cal(int n){
int res=0;
vector<int> num;
while(n)num.push_back(n%10),n/=10;
for(int i=num.size()-1;i>=0;i--){
int d=num[i];
int abc=0,def=0,power=1;
for(int j=i-1;j>=0;j--){
def=def*10+num[j];
power*=10;
}
for(int j=num.size()-1;j>=i+1;j--)abc=abc*10+num[j];
if(d==0)res+=abc*power;
else if(d==1)res+=abc*power+def+1;
else res+=(abc+1)*power;
}
return res;
}
int main(){
int n;
cin>>n;
cout<<cal(n);
}
1059.质因子

- 按序枚举质因子,由于合数会被小于他的质因子提前筛掉,所以不会出现在最终答案
- 复杂情况见算法基础筛质数
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int main(){
int n;
cin>>n;
cout<<n<<"=";
string res;
if(n==1){
cout<<1;
return 0;
}
for(int i=2;i<=n/i;i++){
int sum=0;
while(n%i==0)sum++,n/=i;
if(sum==1)res+=to_string(i)+"*";
else if(sum>1) res +=to_string(i)+"^"+to_string(sum)+"*";
}
if(n>1)res+=to_string (n);
else res.erase(res.size()-1);
cout<<res;
}
1081.有理数的和

- 这道题范围较大,时刻注意对计算结果的化简
- 利用欧几里得算法对分子分母进行化简
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b){
return b? gcd(b,a%b) : a;
}
int main(){
int n;
cin>>n;
LL a=0,b=1;
for(int i=0;i<n;i++){
LL c,d;
scanf("%lld/%lld",&c,&d);
LL t =gcd(c,d);
c/=t,d/=t;
t=gcd(b,d);
a=d/t*a+b/t*c;
b=b/t*d;
t=gcd(a,b);
a/=t,b/=t;
}
if(a>=b){
cout<<a/b;
if(a%b)cout<<" "<<a%b<<"/"<<b;
}
else if(a)cout<<a<<"/"<<b;
else cout<<0;
}
1088.有理数运算 **

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b){
return b ? gcd(b,a%b) : a;
}
void print(LL a,LL b){
LL t = gcd(a,b);
a/=t,b/=t;
if(b<0)a*=-1,b*=-1;
bool is_minus=a<0;
if(is_minus)cout<<"(";
if(b==1)cout<<a;
else {
if(abs(a)>=b)cout<<a/b<<" "<<abs(a)%b<<"/"<<b;
else cout<<a%b<<"/"<<b;
}
if(is_minus)cout<<")";
}
void add(LL a,LL b,LL c,LL d){
print(a,b),cout<<" + ",print(c,d),cout<<" = ";
a=a*d+b*c;
b=b*d;
LL t=gcd(a,b);
a/=t, b/=t;
print(a,b),cout<<endl;
}
void sub(LL a,LL b,LL c,LL d){
print(a,b),cout<<" - ",print(c,d),cout<<" = ";
a=a*d-b*c;
b=b*d;
LL t=gcd(a,b);
a/=t, b/=t;
print(a,b),cout<<endl;
}
void mul(LL a,LL b,LL c,LL d){
print(a,b),cout<<" * ",print(c,d),cout<<" = ";
a=a*c;
b=b*d;
LL t=gcd(a,b);
a/=t, b/=t;
print(a,b),cout<<endl;
}
void div(LL a,LL b,LL c,LL d){
print(a,b),cout<<" / ",print(c,d),cout<<" = ";
if(!c)cout<<"Inf";
else {
a=a*d;
b=b*c;
LL t=gcd(a,b);
a/=t, b/=t;
print(a,b),cout<<endl;
}
}
int main(){
LL a,b,c,d;
scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d);
add(a,b,c,d);
sub(a,b,c,d);
mul(a,b,c,d);
div(a,b,c,d);
}
1096.连续因子

- 枚举起始位置,对于每个起始位置,枚举最大乘积序列长度
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n;
cin>>n;
vector<int>res;
for(int i=2;i<=n/i;i++)
if(n%i==0){
vector<int> seq;
for(int m=n,j=i;m%j==0;j++){
m/=j;
seq.push_back(j);
}
if(seq.size()>res.size())res=seq;
}
if(!res.size())res.push_back(n);
cout<<res.size()<<endl;
cout<<res[0];
for(int i=1;i<res.size();i++)cout<<"*"<<res[i];
}
1103.整数分解 **(二维背包)

- 简化为二维背包问题
f[i][j][k]
- 分析:物品序号
1,2,3...x(x<= ^p√N)
,物品体积1^p,2^p,3^p....x^p
各个物品重量均为1
- 最后要求体积和恰好为
n
,数量恰好为s
的序号和的最大值

- 由于最后求得的状态转移方程不能得到具体选择的方案,我们要
回推整个方案选择
过程 - 观察状态转移方程
f[i,j,k]=max(f[i-1,j,k],f[i,j-i^p,k-1]+i)
可以发现,我们每次从选择i物品和不选i物品两种状态之一发生转移,而题目要求在满足最大序号和的情况下,选择物品字典序越大越好,也就是优先考虑从状态f[i,j-i^p,k-1]+i转移
#include<iostream>
#include<cstring>
using namespace std;
const int N=410;
int f[21][N][N];
int power(int a,int b){
int res=1;
while(b)res*=a,b--;
return res;
}
int main(){
int n,s,p;
cin>>n>>s>>p;
memset(f,-0x3f,sizeof f);
f[0][0][0]=0;
int i;
for(i=1; ;i++){
int v= power(i,p);
if(v>n)break;
for(int j=0;j<=n;j++)
for(int k=0;k<=s;k++){
f[i][j][k]=f[i-1][j][k];
if(j>=v && k)f[i][j][k]=max(f[i][j][k],f[i][j-v][k-1]+i);
}
}
i--;
if(f[i][n][s]<0)cout<<"Impossible"<<endl;
else{
cout<<n<<" = ";
bool is_first=true;
while(i){
int v=power(i,p);
while(f[i][n-v][s-1]+i>=f[i-1][n][s]){
if(is_first)is_first=false;
else cout<<" + ";
cout<<i<<"^"<<p;
n-=v,s-=1;
}
i--;
}
}
}
1104.数段之和

- 前缀和的应用+找规律
- 这题卡精度,开成long double
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
long double num[N],s[N],c[N];
int main(){
int n;
cin>>n;
s[0]=0;
c[0]=0;
long double sum=0;
for(int i=1;i<=n;i++){
cin>>num[i];
s[i]+=s[i-1]+num[i];
c[i]+=c[i-1]+s[i];
sum+=i*s[i]-c[i-1];
}
printf("%.2Lf",sum);
}
1112.卡住的键盘

#include<iostream>
#include<algorithm>
#include<cstring>
#include<unordered_map>
using namespace std;
unordered_map<char,bool> has;
bool st[210];
bool check(char a){
if( (a>='a' && a<='z') || (a>='0' && a<='9'))return true;
else return false;
}
int main(){
int k;
cin>>k;
string s;
cin>>s;
for(int i=0;i<s.size();i++){
if(s[i]!=s[i+1]){
has[s[i]]=true;
}
else {
int len=0;
while(s[i]==s[i+1]){
i++,len++;
}
len++;
if(len % k)has[s[i]]=true;
}
}
string res;
for(int i=0;i<s.size();i++){
if(!has[s[i]]){
if(!st[s[i]]){
cout<<s[i];
st[s[i]]=true;
}
res+=s[i];
i+=k-1;
}
else res+=s[i];
}
cout<<endl<<res;
}
1116.c语言竞赛

#include<iostream>
#include<cstring>
#include<unordered_map>
using namespace std;
const int N=1e4+10;
unordered_map<string,int> has;
unordered_map<string,bool> st;
bool check(int num){
for(int i=2; i<=num/i;i++){
if(num % i ==0)return false;
}
return true;
}
int main(){
int n,k;
cin>>n;
for(int i=1;i<=n;i++){
string s;
cin>>s;
has[s]=i;
}
cin>>k;
while(k--){
string s;
cin>>s;
if(!has[s])cout<<s<<": Are you kidding?"<<endl;
else if(st[s])cout<<s<<": Checked"<<endl;
else{
st[s]=true;
if(has[s]==1)cout<<s<<": Mystery Award"<<endl;
else if(check(has[s]))cout<<s<<": Minion"<<endl;
else cout<<s<<": Chocolate"<<endl;
}
}
}
1152.谷歌的招聘

#include<iostream>
#include<cstring>
using namespace std;
bool check(string n){
int num=atoi(n.c_str());
for(int i=2;i<=num/i;i++){
if(num%i==0)return false;
}
return true;
}
int main(){
int n,k;
cin>>n>>k;
string s;
cin>>s;
bool flag=true;
for(int i=0;i<n-k+1;i++){
string cur=s.substr(i,k);
if(check(cur)){
cout<<cur;
flag =false;
break;
}
}
if(flag)cout<<"404"<<endl;
}