2024.10.4
江守栋
S07246
目录
· 比赛概况
T1 | T2 | T3 | T4 |
AC | 0pts | AC | 70pts |
前三题都能A的,但是T2关了输入输出流同步,再加上文件输入输出,输出出现了一些奇奇怪怪的错误 ,爆零
--->
· 比赛过程
T1 依旧很水 ,5min 秒掉
T2 一眼看上去像是 DP 或 dfs ,找到规律后发现可以直接用二位前缀和写 ,但是自己造了大样例后发现时间在 1s 上下飘忽不定 ,保险起见关了输入输出流同步 ,缺乏经验爆零两行泪
T3 一开始写了个模拟 ,后来找了找规律 ,但是调了很久都与答案差一点 ,于是就非常玄学地改了一些变量想拿部分分 ,结果 AC 了
T4 看上去像是背包 ,没时间写了 ,也没心态写了 ,直接采用六层循环暴力 ,结果数据真的水 ,暴力能拿 70 分
· 题目分析
T1 【下棋(chess)】
1、题目大意
有 个玩家 ,每个玩家有若干个
、
、
星英雄 ,一个
星英雄可以由
个
星英雄合成 ,一个
星英雄可以由
个
星英雄合成 ,记该玩家拥有
、
、
星英雄的数量分别为
、
、
则该玩家的战力为
,根据玩家战力从大到小排序 ,战力相同按序号从小到大排序
2、赛时思路
让 的数量尽量多 ,排个序就行
3、赛时代码&AC代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node{
ll data,id;
}a[100005];
bool cmp(node x, node y){
if(x.data==y.data) return x.id<y.id;
return x.data>y.data;
}
int n;
ll x,y,z;
int main() {
// freopen("chess.in","r",stdin);
// freopen("chess.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
cin>>z>>y>>x;
y+=z/3;
z%=3;
x+=y/3;
y%=3;
a[i].id=i;
a[i].data=18*x+3*y+z;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++) cout<<a[i].id<<' ';
// fclose(stdin);
// fclose(stdout);
return 0;
}
T2 【汪洋(BigWater)】
1、题目大意
n*n的地图中 ,每个格子都有值 ,这些值有正有负 ,主角的初始值是,第一步从
向右走到
,以后每次行进有两种选择:1.按照上一次的方向继续走 2.顺时针旋转
°
从 走若干格子后回到
,期间走过的格子不能再走 ,一个格子中不能连续旋转 ,问走完地图后主角得到的最大值是多少
2、赛时思路
本来想写和
,分析后发现走过的格子一定是一个矩形的四条边 ,最大值即为这四条边的值的和+初始值
,既然有多次求和的过程 ,即可用前缀和优化 ,考虑到地图是一个二维的平面 ,所以可以直接写一个二维前缀和
ps:造出来大样例后关闭了输入输出流 ,老师说因为关闭了输入输出流 ,又没有写 ,所以我的输出就会保留在缓冲区里 ,导致判题机读不到数据 ,从而爆零
3、赛时代码&AC代码
#include<bits/stdc++.h>
using namespace std;
long long n,a[1005][1005],maxx=-0x3f3f3f3f;
long long sum[1005][1005];
int main() {
freopen("BigWater.in","r",stdin);
freopen("BigWater.out","w",stdout);
std::ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j];
for(int i=2;i<=n;i++){
for(int j=2;j<=n;j++){
maxx=max(maxx,sum[1][j]+(sum[i][j]-sum[i][j-1]-a[1][j])+(sum[i][j]-sum[i-1][j]-a[i][j])+(sum[i][1]-a[i][1]));
}
}
cout<<maxx+100;
fclose(stdin);
fclose(stdout);
return 0;
}
T3 【删数(delnum)】
1、题目大意
有一个由正整数从小到大组成的数列 ,还有一个长度为 的数组
每次操作时 ,将数列中第 、
、……
小的数同时移除
有 次询问 ,每次询问输出需要多少次操作才能将
移除 ,如果不可能移除
,则输出
2、赛时思路
对于任何一个 ,如果
<
,那么可以把
前的
个数移除 ,
相对于数列的位置也会变化
当 时 ,
也就在这时被删掉了
3、赛时代码&AC代码
#include<bits/stdc++.h>
using namespace std;
int n,a[100005],q,x;
int ans=0;
bool flag=0;
int main() {
freopen("delnum.in","r",stdin);
freopen("delnum.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
cin>>q;
while(q--){
ans=flag=0;
cin>>x;
for(int i=n;i>=1;i--){
if(x>a[i]){
//ans+=x/i;
//x=x%i;
ans=ans+(x-a[i])/i;
x=a[i]+(x-a[i])%i;
/*
if(x==0||x==a[i]){
flag=1;
break;
}
*/
if(a[i]<x){
x-=i;
ans++;
}
}
if(a[i]==x){
flag=1;
ans++;
break;
}
}
if(flag) cout<<ans<<'\n';
else cout<<0<<'\n';
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
T4 【平分糖果(candy)】
1、题目大意
小可有美味程度分别为 ~
的糖果
美味程度为 的糖果有
个
问小可能不能把糖果平分成美味程度之和相同的两部分
2、赛时思路
没有思路 ,六层循环暴力找答案 ,没想到居然能拿
3、解题思路
考虑动态规划 ,这道题其实就是一个多重背包 ,明确了思路之后代码非常好写
4、AC代码
#include<bits/stdc++.h>
using namespace std;
int sum;
bool dp[10][10000];
int a[10];
int cnt=0;
bool flag;
int main(){
while(1){
cnt++;
memset(dp,0,sizeof dp);
dp[0][0]=1;
flag=0;
sum=0;
for(int i=1;i<=6;i++){
cin>>a[i];
if(a[i]!=0) flag=1;
sum+=a[i]*i;
}
if(flag==0)break;
cout<<"Collection #"<<cnt<<":\n";
if(sum%2){
cout<<"Can't be divided."<<"\n\n";
continue;
}
sum/=2;
for(int i=1;i<=6;i++){
for(int j=0;j<=sum;j++){
for(int k=0;k<=a[i];k++){
if(j<k*i){
break;
}
dp[i][j]|=dp[i-1][j-k*i];
}
}
}
if(dp[6][sum]){
cout<<"Can be divided.\n\n";
}
else{
cout<<"Can't be divided."<<"\n\n";
}
}
return 0;
}
· 赛后总结
今天总体来说还可以 ,可惜的是没遇到过在文件读写情况下关闭输入输出同步的情况 ,如果关闭了,就应该在输入后加上 ,或者压根不关闭 ,用
、
T3 本来没有清晰的思路 ,但是手推样例后找到了做法 ,以后如果有题没有思路 ,手推样例就好
T4 应该多想一想,转化成多重背包后就很好解了