| 题目 | 难度 | 知识点 |
|---|---|---|
| A 智乃办赛 | ★ | 签到 |
| B 智乃的Wordle | ★ | 签到 |
| C 智乃的数字 | ★★ | 打表/容斥+二分 |
| D 智乃与长短期主义者博弈 | ★★ | 区间DP |
智乃办赛
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
int n; cin>>n;
int cnt=n/500;
if( n%500 == 0) cout<<char('A'+cnt-1)<<"500";
else
{
cout<<char('A'+cnt);
printf("%03d",n%500);
}
return 0;
}
智乃的Wordle
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int main()
{
string a,b; cin>>a>>b;
map<char,int>mp;
for(int i=0;i<a.size();i++) mp[a[i]]++;
for(int i=0;i<a.size();i++)
{
if(a[i]==b[i]) cout<<'g';
else if(a[i]!=b[i]&&mp[b[i]]) cout<<'y';
else cout<<'r';
}
puts("");
if(a==b) cout<<"congratulations";
else cout<<"defeat";
return 0;
}
智乃的数字
#include <bits/stdc++.h>
using namespace std;
bool check(int x)
{
int w=x%10;
if(w==5) return 1;
int cnt=0;
while(x) cnt+=(x%10),x/=10;
if(cnt%3==0) return 1;
return 0;
}
vector<int>ve;
int a[8]={0,2,4,6,6,4,2,6};
int s[8]={0,2,6,12,18,22,24,30};
int main()
{
/*for(int i=1;i<=1000;i+=2) if(check(i)) ve.push_back(i);
for(int i=1;i<ve.size();i++) cout<<ve[i]-ve[i-1]<<endl;*/
int t; cin>>t;
while(t--)
{
int k; cin>>k;
k--;
long long int ans=3;
cout<<ans+(k/7)*30ll+s[k%7]<<'\n';
}
return 0;
}
//2,4,6,6,4,2,6=30
容斥+二分
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL check(LL x)
{
return x/3+x/5-x/6-x/10-x/15+x/30;
}
void solve(int x)
{
LL l=3,r=1e18;
while(l<r)
{
LL mid=(l+r)/2;
if(check(mid)<x) l=mid+1;
else r=mid;
}
cout<<l<<endl;
}
int main(void)
{
int t; cin>>t;
while(t--)
{
int n; cin>>n;
solve(n);
}
return 0;
}
智乃与长短期主义者博弈
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N][N],a[N],n,sum;
//f[i][j] 指的是[i,j]区间内,长期的最大值.
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
memset(f,-0x3f,sizeof f);
for(int i=1;i<=n;i++) f[i][i]=0;
for(int i=2;i<=n;i++) f[i-1][i]=min(a[i-1],a[i]);
for(int len=3;len<=n;len++)
{
for(int i=1;i<=n;i++)
{
int l=i,r=i+len-1;
if(r>n) break;
if(a[l]>=a[r]) f[l][r]=max(f[l+1][r-1]+a[r],f[l+2][r]+a[l+1]);
else f[l][r]=max(f[l][r-2]+a[r-1],f[l+1][r-1]+a[l]);
}
}
cout<<sum-f[1][n]<<" "<<f[1][n];
return 0;
}
动态规划+记忆化搜索
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N][N],a[N],n,sum;
//f[i][j] 指的是[i,j]区间内,长期的最大值.
int dfs(int l,int r)
{
if(l==r)
{
f[l][r]=0;
return f[l][r];
}
if( r-l+1 == 2)
{
f[l][r]=min(a[l],a[r]);
return f[l][r];
}
if(f[l][r]!=-1) return f[l][r];
int ans=0;
if(a[l]>=a[r])
{
ans=max(ans,dfs(l+2,r)+a[l+1]);
ans=max(ans,dfs(l+1,r-1)+a[r]);
}else
{
ans=max(ans,dfs(l,r-2)+a[r-1]);
ans=max(ans,dfs(l+1,r-1)+a[l]);
}
f[l][r]=ans;
return f[l][r];
}
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
memset(f,-1,sizeof f);
int ans=dfs(1,n);
cout<<sum-ans<<" "<<ans;
return 0;
}