题目:3416. 时间显示
题解:模拟+字符串处理
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,double>PII;
const int N=2e5+10;
const int mod=1000000009;
LL n;
int main(){
cin>>n;
n/=1000;
int s=n%60;
n/=60;
int m=n%60;
n/=60;
int h=n%24;
printf("%02d:%02d:%02d",h,m,s);
return 0;
}
题目:3417. 砝码称重
题解一:每个砝码有三种选择(不选、放左边、放右边)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,double>PII;
const int N=1e5+10;
const int mod=1000000009;
int n;
bool c1[N]={0},c2[N]={0};
int w[110];
int main(){
cin>>n;
for(int i=0;i<n;i++)
cin>>w[i];
for(int i=0;i<n;i++){
c1[0]=1;
memset(c2,0,sizeof c2);
for(int j=0;j<=100000;j++){
if(j+w[i]<=100000)c2[j+w[i]]=c2[j+w[i]]||c1[j];
c2[abs(j-w[i])]=c2[abs(j-w[i])]||c1[j];
// if(c2[j+w[i]]) cout<<j+w[i]<<" ";
// if(c2[abs(j-w[i])]) cout<<abs(j-w[i])<<" ";
c2[j]=c2[j]||c1[j];
}
//cout<<endl;
memcpy(c1,c2,sizeof c2);
}
int ans=0;
for(int i=1;i<=100000;i++){
if(c1[i]) {
ans++;
}
}
cout<<ans;
return 0;
}
题解二:dp,背包问题
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,double>PII;
const int N=1e5+10;
const int mod=1000000009;
int n;
int w[110];
bool f[110][N];
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>w[i];
f[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=100000;j++){
if(w[i]+j<=100000){
f[i][w[i]+j]=f[i-1][j]||f[i-1][w[i]+j]||f[i][w[i]+j];
}//放左边
f[i][abs(j-w[i])]=f[i][abs(j-w[i])]||f[i-1][j]||f[i-1][abs(j-w[i])];
//放右边
f[i][j]=f[i][j]||f[i-1][j];
//两边都不放
}
}
int ans=0;
for(int i=1;i<=100000;i++){
if(f[n][i]) ans++;
}
cout<<ans;
return 0;
}
题目:3422. 左孩子右兄弟
题解:树型dp。最大的深度maxd一定是由子节点的数量ct_son+子节点中最大的深度d_son组成(实际上就是求子节点中儿子数量的最大值)。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,double>PII;
const int N=1e5+10;
const int mod=1000000009;
int n;
vector<int > g[N];
int dp[N];
void dfs(int u){
dp[u]=g[u].size();
int sum=0;
for(int i=0;i<g[u].size();i++){
int t=g[u][i];
dfs(t);
sum=max(sum,dp[t]);
}
dp[u]+=sum;
}
int main(){
cin>>n;
int x;
for(int i=2;i<=n;i++){
scanf("%d",&x);
g[x].push_back(i);
}
dfs(1);
cout<<dp[1];
return 0;
}
题目:3424. 最少砝码
**题解:数学题。假设k个数可以称出1 ~ n,那么再➕上一个数,值为2n+1.这时可以称出1 ~ 3n+1,当只有一个砝码1时,称出1种,砝码数为2时(分别为1,3),称出1*3+1=4种(1,3,2,4)。以此类推,有k个砝码,可以称出3(k-1)+3(k-2)+…+3^0 = (3^k-1)/2。这时只要该值>=n即可 **
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,double>PII;
const int N=1e5+10;
const int mod=1000000009;
int main(){
int n;
cin>>n;
cout<<ceil(log(2*n+1)/log(3));
return 0;
}