A. Drinks Choosing
签到题,就是对每一种饮料都可以拿好多次,在拿饮料总和有限的条件下,问最多能够满足多少人
# include <bits/stdc++.h>
using namespace std;
const int MAXN=1e3+100;
int a[MAXN];
int main()
{
int n,k;
int sum=0;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
int aa;
scanf("%d",&aa);
a[aa]++;
}
int b;
if(n%2==0) b=n/2;
else b=n/2+1;
int c;
for(int i=1;i<=k;i++){
if(a[i]!=1){
c=a[i]/2;
if(c<=b){
sum+=c*2;
a[i]=a[i]/2*2;
b=b-c;
}else{
sum+=b*2;
a[i]=a[i]-b*2;
b=0;
break;
}
}
}
//cout<<"@@@"<<sum<<endl;
if(b){
for(int i=1;i<=k;i++){
if(b){
if(a[i]){
sum+=1;
a[i]=0;
b--;
}
}
}
}
printf("%d",sum);
return 0;
}
B. Sport Mafia
解一个方程即可,a*(a+1)/2-b=k,其中a+b==n;
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
LL n,k;
scanf("%lld %lld",&n,&k);
LL sum=0;
sum=(sqrt(9+8*(n+k))-3)/2;
printf("%lld",n-sum);
return 0;
}
C. Basketball Exercise
一维DP,总共有三种,对于当前的取h1[ i ],h2[ i ],不取列三个状态转移方程即可
# include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+100;
typedef long long LL;
LL h1[MAXN];
LL h2[MAXN];
LL f[MAXN][3];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&h1[i]);
}
for(int i=1;i<=n;i++){
scanf("%lld",&h2[i]);
}
for(int i=1;i<=n;i++){
f[i][0]=max(max(f[i-1][0],f[i-1][1]),f[i-1][2]);
f[i][1]=max(f[i-1][0],f[i-1][2])+h1[i];
f[i][2]=max(f[i-1][0],f[i-1][1])+h2[i];
}
cout<<max(max(f[n][0],f[n][1]),f[n][2]);
return 0;
}
D1. Submarine in the Rybinsk Sea (easy edition)
由于位数是一样的所以,(用12来举例好了),会变成1_2_,或者_1_2,每种有n个,相应计算即可
# include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+100;
typedef long long LL;
LL a[MAXN];
LL mod=998244353;
int main()
{
int n;
LL ans=0;
LL sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
int b=11;
while(a[i]){
ans=(ans+(b*(a[i]%10))%mod)%mod;
b=((b%mod)*100)%mod;
a[i]=a[i]/10;
//cout<<b<<endl;
//cout<<"@@@"<<ans<<endl;
}
//cout<<ans<<endl;
sum=(sum%mod+ans)%mod;
ans=0;
}/*
for(int i=1;i<=n;i++){
LL t=11;
while(a[i]>0) ans=(1ll*a[i]%10*t)%mod,t=t*100%mod,a[i]=a[i]/10;
cout<<ans<<endl;
}*/
sum=(n*sum)%mod;
printf("%lld",sum);
return 0;
}
D2. Submarine in the Rybinsk Sea (hard edition)
和上面一个不一样的地方在于长度不一样了,那么可以这么想,对于每个数同一位的数字的地位是一样的,那么我们可以把这些加起来,当成一个去处理。对于每一位,位数相同的那么和上一题是一样的,但是位数多的哪一个,那么就是不在有位数的差,就是等于算了两次的那一位
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL mod=998244353;
const int MAXN=1e5+100;
char a[MAXN][30];
LL wei[30];
LL quick_pow(LL a,LL b)
{
LL ret=1;
while(b)
{
if(b&1) ret=ret*a%mod;
a=a*a%mod;
b=b/2;
}
return ret%mod;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",&a[i]);
for(int j=0;j<strlen(a[i]);j++){
wei[strlen(a[i])-j]+=a[i][j]-'0';
}
}
LL sum=0;
for(int i=1;i<=n;i++){
int k=1;
LL t=11;
for(int j=0;j<strlen(a[i]);j++){
sum=(sum+(wei[k]*t%mod))%mod;
t=((t%mod)*100%mod);
k++;
}
for(;k<20;k++){
sum=(sum+wei[k]*quick_pow(10,strlen(a[i])+k-1)%mod*2%mod)%mod;
}
}
cout<<sum<<endl;
return 0;
}