upd: T4 重新上传 AC 代码,一开始的有 hack。
姓名:王胤皓,校区:和谐校区,考试时间: 2024 2024 2024 年 10 10 10 月 2 2 2 日 9 : 00 : 00 9:00:00 9:00:00~ 12 : 30 : 00 12:30:00 12:30:00,学号: S 07738 S07738 S07738
请关注作者的 B 站,谢谢~链接
CSP-J Day 2 2 2 模拟赛补题报告
前言
考了我们班 Rank 2 2 2。
分数
T1 chess:
A
c
c
e
p
e
t
e
d
100
\color{green}Accepeted\space100
Accepeted 100
T2 BigWater:
A
c
c
e
p
e
t
e
d
100
\color{green}Accepeted\space100
Accepeted 100
T3 delnum:
W
r
o
n
g
_
a
n
s
w
e
r
20
\color{red}Wrong\_answer\space20
Wrong_answer 20
T4 candy:
T
L
E
&
W
r
o
n
g
_
A
n
s
w
e
r
5
5
\color{orange}TLE\color{black}{\&}\color{red}Wrong\_Answer\space\color{orange}5\color{red}5
TLE&Wrong_Answer 55
T1
题面
思路
贪心。
让输入的最后一个数字最大,第二个次大,第一个最小,然后计算,排序,就完了。
代码
#include<bits/stdc++.h>
using namespace std;
struct node{
long long sum,i;
}t[100005];
bool cmp(node a,node b){
if(a.sum==b.sum) return a.i<b.i;
else return a.sum>b.sum;
}
int main(){
freopen("chess.in","r",stdin);
freopen("chess.out","w",stdout);
int n;
cin>>n;
for(int i=1; i<=n; i++){
int a,b,c;
cin>>a>>b>>c;
b+=a/3;
a%=3;
c+=b/3;
b%=3;
t[i].sum=18*1ll*c+3*1ll*b+1ll*a;
t[i].i=i;
}
sort(t+1,t+n+1,cmp);
for(int i=1; i<=n; i++) cout<<t[i].i<<" ";
return 0;
}
T2
题面
思路
首先,我们发现,他走的一定是一个长方形的边框,如果再转一次,那么就永远出不来了,所以使用二维前缀和,然后计算最大值,请注意,一开始最大值赋值为一个非常小的负数,最后再加上 100 100 100 就行了。
代码
#include<bits/stdc++.h>
using namespace std;
int n,a[1005][1005];
int main(){
freopen("BigWater.in","r",stdin);
freopen("BigWater.out","w",stdout);
cin>>n;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
cin>>a[i][j];
a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
}
int ans=-0x3f3f3f3f;
for(int i=2; i<=n; i++){
for(int j=2; j<=n; j++){
ans=max(ans,a[1][j]+a[i][1]+(a[i][j]-a[i-1][j]-a[i][1]+a[i-1][1])+(a[i-1][j]-a[i-1][j-1]-a[1][j]+a[1][j-1]));
}
}
cout<<100+ans;
return 0;
}
T3
题面
思路
如果删除的 x x x 的范围为: a i ≤ x ≤ a i + 1 a_i\le x\le a_{i+1} ai≤x≤ai+1,此时可以删除 x x x 前 i i i 个数, x x x 发生变化,后面不用考虑。
如果 a i = x a_i=x ai=x,结束,输出。
如果最后也没有删除,那么输出 0 0 0。
综上,我们需要考虑的是 a i ≤ x ≤ a i + 1 a_i\le x\le a_{i+1} ai≤x≤ai+1 中的 i i i 的位置。
可以发现, i i i 是递减的,所以说,总时间复杂度为 O ( n ) O(n) O(n)。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int n;
cin>>n;
int a[100005];
for(int i=1; i<=n; i++){
cin>>a[i];
}
int q;
cin>>q;
while(q--){
int x;
cin>>x;
int ans=0,flag=0;
for(int i=n; i>=1; i--){
if(a[i]<x){
ans+=(x-a[i])/i;
x=a[i]+(x-a[i])%i;
if(x>a[i]){
x-=i;
ans++;
}
}
if(a[i]==x){
ans++;
flag=1;
break;
}
}
if(flag) cout<<ans<<"\n";
else cout<<0<<'\n';
}
return 0;
}
T4
题面
思路
多重背包,加上二进制优化,就过了(糖丸了)。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int dp[120000];
signed main(){
int a,b,c,d,e,f,cnt=1;
while(cin>>a>>b>>c>>d>>e>>f){
if(!a&&!b&&!c&&!d&&!e&&!f){
break;
}
printf("Collection #%d:\n",cnt);
cnt++;
if((a+2*b+3*c+4*d+5*e+6*f)%2==1){
cout<<"Can't be divided.\n\n";
}
else{
int g[]={0,a,b,c,d,e,f};
if(a+b+c+d+e+f==1){
cout<<"Can't be divided.\n\n";
continue;
}
dp[0]=1;
int will=(a+2*b+3*c+4*d+5*e+6*f);
for(int i=1; i<=6; i++){
for(int k=1; k<=g[i]; k<<=1){
for(int j=will;j>=i*k;j--){
dp[j]=dp[j]|dp[j-i*k];
}
g[i]-=k;
}
if(g[i]){
for(int j=will; j>=i*g[i]; j--) dp[j]=dp[j]|dp[j-i*g[i]];
}
}
if(dp[will>>1]) cout<<"Can be divided.\n\n";
else cout<<"Can't be divided.\n\n";
memset(dp,0,sizeof dp);
}
}
return 0;
}