日期:2023.10.2
学号:S06465
一:
总分数:
T1【下棋(chess)】:70
T2【汪洋(BigWater)】:20
T3【删数(delnum)】:20
T4【平分糖果(candy)】:20
二、比赛过程
第一题比较简单,暴力就能过,不过要开long long,我只开了sum的,x,y,z没开,在计算过程中爆int了
第二题用暴搜骗得分
第三题是用的暴力计算、打表
第四题是用的比较暴力的写法
三、比赛分析
T1【下棋(chess)】:
1.题目大意
一共有n组数,每次输入z,y,x,三个z可以合成一个y,三个y可以合成一个x,其中阵容强度为18x+3y+z,让你按阵容强度顺序输出玩家的序号(若阵容强度相同,则按玩家序号排序)
2.比赛中的思考
直接根据题目描述换算,计算总和,最后排一个序就行了,但是我没注意x,y,z,在计算过程中爆int了30分就水灵灵的没了
3.解题思路
根据题目要求换算,计算,最后用sort排一个序,输出就行(一定要注意开long long)
4.AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n;
struct node{
long long x,y,z;
long long sum;
int id;
}a[N];
int cmp(node a,node b){
if(a.sum==b.sum){
return a.id<b.id;
}
return a.sum>b.sum;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].z,&a[i].y,&a[i].x);
a[i].y+=a[i].z/3;
a[i].z%=3;
a[i].x+=a[i].y/3;
a[i].y%=3;
a[i].sum=18*a[i].x+3*a[i].y+a[i].z;
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
printf("%d ",a[i].id);
}
return 0;
}
T2【汪洋(BigWater)】:
1.题目大意
从(1,1)点向右出发,每次移动只能移动到一个相邻的格子,每次可以沿着上一步的方向继续移动,或进行顺时针90度转向,而且不再逛那些逛过的格子(起点除外),最后要回到(1,1),问最大的心情值是多少
2.比赛中的思考
没有什么思路,看了一眼数据,写了一个暴搜偏分
3.解题思路
通过模拟样例可以发现,她每次都是走了一个矩形的边,求出每行每列的前缀和,最后利用前缀和求解就行了
4.AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n;
int a[N][N];
int r[N][N];
int c[N][N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
r[i][j]=r[i][j-1]+a[i][j];
c[i][j]=c[i-1][j]+a[i][j];
}
}
int ans=-0x3f3f3f3f;
for(int i=2;i<=n;i++){
for(int j=2;j<=n;j++){
ans=max(ans,r[1][j-1]+c[i-1][j]+r[i][j]+c[i-1][1]);
}
}
printf("%d",ans+100);
return 0;
}
T3【删数(delnum)】:
1.题目大意
给一个长度为n的数组a,每次操作将第a[1]小、第a[2]小...第a[n]小的数同时移除,有q次询问,问从初始状态到删除x需要操作多少次,如果无法删除输出0
2.比赛中的思考
没想到什么比较正经的解法,直接暴力去做的
3.解题思路
根据模拟样例,可以发现公式,直接带入计算一下就行了
4.AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N];
int n;
int q;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
scanf("%d",&q);
while(q--){
int x;
scanf("%d",&x);
int ans=0;
int 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){
printf("%d\n",ans);
}
else{
printf("0\n");
}
}
return 0;
}
T4【平分糖果(candy)】:
1.题目大意
已知美味程度为i的糖果有a[i]个,问能不能把糖果平分成美味程度之和相同的两部分
2.比赛中的思考
没思路,写的偏分代码
3.解题思路
用dp[i][j]表示前i种物品,能否凑出价值j来,根据这个推出公式,计算就可以了
4.AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1.2e5+5;
int mark;
int a[10];
bool f[N];
int main(){
while(~scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])){
int m=a[1]+a[2]*2+a[3]*3+a[4]*4+a[5]*5+a[6]*6;
if(!m){
break;
}
else{
for(int i=1;i<=m;i++){
f[i]=0;
}
}
printf("Collection #%d:\n",++mark);
f[0]=1;
for(int i=1;i<=6;i++){
for(int k=1;k<=a[i];k<<=1){
for(int j=m;j>=i*k;j--){
f[j]=f[j]|f[j-i*k];
}
a[i]-=k;
}
if(a[i]){
for(int j=m;j>=i*a[i];j--){
f[j]=f[j]|f[j-i*a[i]];
}
}
}
if(!(m&1)&&f[m>>1]){
printf("Can be divided.\n");
}
else{
printf("Can't be divided.\n");
}
printf("\n");
}
return 0;
}