第A题(01背包dp)有一个数字根的结论
方法1:(不知道结论的,需要计算出数字根)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int N = 1e5+8;
const int mod = 998244353;
ll t,n,m,a[N],sum[N],dp[N][10];
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
ll now = 0;
if(a[i]>=10){
while(a[i]>=10){//数字根
now = 0;
while(a[i]){
now+=a[i]%10;
a[i]/=10;
}
a[i]=now;
}
a[i]=now;
}
}
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=9;j++){
dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;
ll now = j+a[i];
if(now>=10)now=1+now%10;
dp[i][now]=(dp[i][now]+dp[i-1][j])%mod;
}
dp[i][a[i]]=(dp[i][a[i]]+1)%mod;
}
for(int i=1;i<=9;i++){
cout<<dp[n][i]<<' ';
}
return 0;
}
方法2:
数字根结论:一个数的数字根等于这个数对9取模的结果(特殊的:取模为0的数字根为9)
#include<bits/stdc++.h>
#define fors(i,a,b) for(int i = a; i < b; ++i)
#define ll long long
using namespace std;
const int maxn = 1e5+5;
int f[maxn][9];
const int mod = 998244353;
int main(){
int n; cin>>n;
f[0][0] = 1;
fors(i,1,n+1){
int x; scanf("%d", &x); x %= 9;
fors(j,0,9){
f[i][(j+x)%9] = (f[i][(j+x)%9] + f[i-1][j])%mod;
f[i][j] = (f[i][j]+f[i-1][j])%mod;
}
}
fors(i,1,9) cout<<f[n][i]<<" "; cout<<f[n][0]-1<<endl;
return 0;
}
第C题(难点在理解题意)模拟
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[105];
int n;
int ans=0;
cin>>n;
a[0]=0;
for(int i=1;i<=n;i++){
a[i]=a[i-1]+1;
for(int j=1;j<=3;j++){
int now;
cin>>now;
if(now==1){
a[i]=max(a[i-j]+4,a[i]);
}
}
}
cout<<a[n]-n;
return 0;
}
第E题(想公式,模拟会超时)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1007;
int main()
{
int t,n,m,ans;
cin>>t;
while(t--)
{
ans=0;
cin>>n>>m;
if(m==1)
{
if(n==1) cout<<"1"<<"\n";
else cout<<"-1"<<"\n";
}
else
{
ans=((n-1)/(m-1)+((n-1)%(m-1)!=0))*2-1;
cout<<ans<<"\n";
}
}
return 0;
}
/*
把n个东西 每次减少m个 减少多少次能变成0
公式:n/m+(n%m!=0)
*/
第J题 (涉及前缀和,结构体等等)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+15;
ll va[N],vb[N];
bool cmp(int xx,int yy)
{
return xx>yy;
}
int suma[N],sumb[N];
int main()
{
int T,A,B,n;
cin>>T;
while(T--)
{
cin>>A>>B>>n;
for(int i=1;i<=A;++i)
{
cin>>va[i];
}
for(int i=1;i<=B;++i)
{
cin>>vb[i];
}
int mxb=min(n/2,B);//为后面的数量判断准备
if(A+mxb<n)//特判不合题意的
{
cout<<"-1"<<"\n";
continue;
}
sort(va+1,va+1+A,cmp);
sort(vb+1,vb+1+B,cmp);
for(int i=1;i<=A;++i)
{
suma[i]=suma[i-1]+va[i];//前缀和
}
for(int i=1;i<=B;++i)
{
sumb[i]=sumb[i-1]+vb[i];
}
int ans=-1;
for(int i=0;i<=A;++i)
{
int j=n-i;
if(j>mxb||j<0) continue;
ans=max(ans,suma[i]+sumb[j]);
}
cout<<ans<<"\n";
}
return 0;
}
第L题(签到题):
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1007;
char a[N];
int main()
{
double n,m;
double ans,x,y;
scanf("%lf",&n);
while(n--)
{
x=0;
y=0;
ans=0;
scanf("%lf",&m);
scanf("%s",a);
for(int i=0;i<m;++i)
{
if(a[i]=='U')
{
y+=1;
}
if(a[i]=='D')
{
y-=1;
}
if(a[i]=='R')
{
x+=1;
}
if(a[i]=='L')
{
x-=1;
}
double len;
len=pow(x,2)+pow(y,2);
len=sqrt(len);
if(ans<len)
{
ans=len;
}
}
printf("%.10lf\n",ans);
}
return 0;
}