试题 A: 2022
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL dp[11][2023];
int main()
{
dp[0][0]=1;
for(int i=1;i<=2022;i++)
for(int j=10;j>=1;j--)
for(int k=i;k<=2022;k++)
dp[j][k]+=dp[j-1][k-i];
cout<<dp[10][2022]<<endl;
return 0;
}
试题 B: 钟表
#include<bits/stdc++.h>
using namespace std;
int main()
{
for(int s=0;s<=6;s++)
for(int f=0;f<60;f++)
for(int m=0;m<60;m++)
{
double m1=1.0*m/60*360;
double f1=1.0*f/60*360+m1/60;
double s1=1.0*s/12*360+f1/12;
double A=fabs(f1-s1),B=fabs(f1-m1);
A=min(A,360-A);B=min(B,360-B);
if(fabs(A-2*B)<=1e-5)
cout<<s<<" "<<f<<" "<<m<<endl;
}
return 0;
}
试题 C: 卡牌
思路:现在一副牌有n种牌,当前每种牌a[i]张,m张白色牌,把m张白色牌分给当前有的a[i]牌中,但不能超过b[i],求最大能凑出几副牌。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200010;
int a[N],b[N],n;
LL m;
bool check(int mid)
{
LL sum=0;
for(int i=1;i<=n;i++)
if(a[i]<mid)
{
sum+=mid-a[i];
if(mid>a[i]+b[i]) return false;
if(sum>m) return false;
}
return true;
}
int main()
{
scanf("%d%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
int l=0,r=1e6;
while(l<r)
{
int mid=(l+r+1)>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
return 0;
}
试题 D: 最大数字
思路:
2
n
2^n
2n次状态压缩,暴力搜索,判断当前情况是否符合条件。
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;int aa,bb;cin>>s>>aa>>bb;
int n=s.size();
string mx=s;
for(int i=0;i<(1<<n);i++)
{
string str=s;
int a=aa,b=bb;
for(int j=n-1,k=0;j>=0;j--,k++)
{
if(i>>j&1)
{
if(a==0) continue;
int x=s[k]-'0';
int d=9-x;
if(d<=a) a-=d,str[k]='9';
else str[k]=x+a+'0',a=0;
}
else
{
if(b==0) continue;
int x=s[k]-'0';
int d=x+1;
if(d<=b) b-=d,str[k]='9';
else str[k]=x-b+'0',b=0;
}
}
mx=max(mx,str);
}
cout<<mx<<endl;
return 0;
}
试题 E: 出差
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010;
vector<PII> g[N];
int d[N];
bool st[N];
int main()
{
int n,m;cin>>n>>m;
vector<int> w(n+1);
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=m;i++)
{
int a,b,c;cin>>a>>b>>c;
g[a].push_back({b,c});
g[b].push_back({a,c});
}
memset(d,0x3f,sizeof d);
memset(st,false,sizeof st);
d[1]=0;
priority_queue<PII,vector<PII>,greater<PII> > Q;
Q.push({d[1],1});
while(!Q.empty())
{
PII t=Q.top();Q.pop();
int ver=t.second,distance=t.first;
if(st[ver]) continue;
st[ver]=true;
for(auto &p:g[ver])
{
int j=p.first,v=p.second;
if(d[j]>distance+v+w[ver])
{
d[j]=distance+v+w[ver];
Q.push({d[j],j});
}
}
}
cout<<d[n]-w[1]<<endl;
return 0;
}
试题 H: 机房
思路:给你一个树,求任意两点之间的所有点——直接连接点的数量和,LCA模板题。但是不会LCA,待补。