G. Grade Point Average
思路:
k最多1e5位
手工除法模拟
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod =1e9+7;
int main(){
int n,k;
scanf("%d%d",&n,&k);
int sum=0;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
sum+=x;
}
printf("%d.",sum/n);
sum%=n;
while(k--){
sum*=10;
printf("%d",sum/n);
sum%=n;
}
return 0;
}
Dyson Box
思路:
每个箱子如果不与其他箱子相邻,那么贡献是4,
现考虑竖直方向的重力:
如果当前列之前不存在箱子,那么现在加入的这个箱子的贡献值为4;
如果当前列已经存在其他箱子,那么现在加入的这个箱子贡献值减2(在4的基础上);
与此同时,若前一列的箱子数量大于当前列(向下推箱子到底,当前箱子就会与前一列的某个箱子相邻),那么现在加入的这个箱子贡献值再减2;
若后一列的箱子数量也大于当前列,那么现在加入的这个箱子贡献值再减2。
水平方向的重力同理。
注意开longlong
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod =1e9+7;
int xx[maxn],yy[maxn];
int main(){
int n;
cin>>n;
ll ans1=0;
ll ans2=0;
for(int i=0;i<n;i++){
int x,y;
cin>>x>>y;
ans1+=4,ans2+=4;
if(xx[x]) ans1-=2;
if(x>=1&&xx[x-1]>xx[x]) ans1-=2;
if(xx[x+1]>xx[x]) ans1-=2;
if(yy[y]) ans2-=2;
if(y>=1&&yy[y-1]>yy[y]) ans2-=2;
if(yy[y+1]>yy[y]) ans2-=2;
xx[x]++;
yy[y]++;
cout<<ans1<<" "<<ans2<<endl;
}
return 0;
}
H. Adventurer’s Guild
思路:
二维背包
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]:前
i
i
i个怪物,当前血量为
j
j
j,消耗
k
k
k耐力时能够获得的最大价值。
动态转移方程:
d
p
[
i
]
[
j
]
[
k
]
=
m
a
x
(
d
p
[
i
]
[
j
]
[
k
]
,
d
p
[
i
−
1
]
[
j
−
h
[
i
]
−
m
a
x
(
0
,
s
[
i
]
−
k
)
]
[
m
a
x
(
0
,
k
−
s
[
i
]
)
]
+
w
[
i
]
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-h[i]-max(0,s[i]-k)][max(0,k-s[i])]+w[i]
dp[i][j][k]=max(dp[i][j][k],dp[i−1][j−h[i]−max(0,s[i]−k)][max(0,k−s[i])]+w[i]
利用滚动数组降维
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+10;
const int mod =1e9+7;
int h[maxn],s[maxn],w[maxn];
ll dp[maxn][maxn];
int main(){
int n,H,S;
scanf("%d%d%d",&n,&H,&S);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&h[i],&s[i],&w[i]);
}
for(int i=1;i<=n;i++){
for(int j=H;j>=1;j--){
for(int k=S;k>=0;k--){
if(j>h[i]&&j+k>s[i]+h[i]){
dp[j][k]=max(dp[j][k],dp[j-h[i]-max(0,s[i]-k)][max(0,k-s[i])]+w[i]);
}
}
}
}
printf("%lld\n",dp[H][S]);
return 0;
}
Matrix Problem
思路:
思维+构造
Cat Virus
思路:
对于每个父亲结点,都有两种涂色方法,