模拟赛二补题报告

模拟赛二补题报告

李智航S13494

前言

·下棋(chess)
·汪洋(BigWater)
·删数(delnum)
·平分糖果(candy)

一.题目报告

比赛中,第一题AC,第二题与第四题都爆了(运行错误),第二题5分,第四题35分,第三题直接爆0;

二.赛中概况

第一题那个数据范围是真的恶心,需要开long long,第二题wa一堆,第三题没时间,直接打了一个自己都不知道的东西,第四题吧范围看错了,少打了一个0,痛失65分。

三.解题报告

1.下棋(chess)

1.题目描述:

在这里插入图片描述
在这里插入图片描述

2.开始代码如下:

#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define ll long long
struct S{
	ll x,y,z;//z为一星,y为两星,x为三星 
	ll all;
	ll num;
}a[100001];
bool cmp(S a1,S b1){
	if(a1.all==b1.all){
		return a1.num<b1.num;
	}
	return a1.all>b1.all;
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].z>>a[i].y>>a[i].x;
		a[i].num=i;
	}
	for(int i=1;i<=n;i++){
		int zz=a[i].z/3;
		a[i].z%=3;
		a[i].y+=zz;
		int yy=a[i].y/3;
		a[i].y%=3;
		a[i].x+=yy;
	}
	for(int i=1;i<=n;i++){
		a[i].all=18*a[i].x+3*a[i].y+a[i].z;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++){
		cout<<a[i].num<<" ";
	}
	return 0;
}

思路:直接暴力,通过题目可得18x+3y+z,3个换一个更高级的,3z换y,所以z和y换不换一样,但是3y=x,但一个x的价值是18.两个价值相差很大。所以直接转换就行,不需要考虑不换的情况。

3.正解

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
struct player{
	long long x,y,z,sum;
	int num;
}a[100005];
bool cmp(player a,player b){
	if(a.sum!=b.sum) return a.sum>b.sum;
	else return a.num<b.num;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld %lld %lld",&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=a[i].x *18+a[i].y*3+a[i].z;
		a[i].num=i;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++) printf("%d ",a[i].num);
	return 0;
} 

2.汪洋(BigWater)

1.题目:

在这里插入图片描述在这里插入图片描述

2.开始题目代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 205;
int n;
int a[N][N];
bool v[N][N];
// 方向数组:右、下、左、上
int dx[]= {0,1,0,-1};
int dy[]= {1,0,-1,0};
void dfs(int x,int y,int fx,int m,int &mm) {
	mm=max(mm,m);
	int nx=x+dx[fx];
	int ny=y+dy[fx];
	if(nx>=0&&nx<n&&ny>=0&&ny<n&&!v[nx][ny]) {
		v[nx][ny]=true;
		dfs(nx,ny,fx,m+a[nx][ny],mm);
		v[nx][ny]=false;
	}
	int nfx=(fx+1)%4;
	nx=x+dx[nfx];
	ny=y+dy[nfx];
	if (nx>=0&&nx<n&&ny>=0&&ny<n&&!v[nx][ny]) {
		v[nx][ny]=true;
		dfs(nx,ny,nfx,m+a[nx][ny],mm);
		v[nx][ny]=false;
	}
}

int main() {
	cin>>n;
	for(int i=0; i<n; i++) {
		for(int j=0; j<n; j++) {
			cin>>a[i][j];
		}
	}
	v[0][0]=true;
	int mm=100;
	dfs(0,0,0,100,mm);
	cout<<mm<<endl;
	return 0;
}

思路:(直接交给电脑) ,就是一直往下找,把所有地点遍历一遍,但忘了覆盖之前的答案。
只能顺时针转弯,,所以就是一直走和转弯两种情况递归。

3.正解:

#include<bits/stdc++.h>
using namespace std;
long long n,r[1001][1001],c[1001][1001],a[1001][1001],ans=-1145141; 
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
			r[i][j]=r[i][j-1]+a[i][j];
			c[i][j]=c[i-1][j]+a[i][j];
    	}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			ans=max(ans,r[i][j]+r[1][j]+c[i][j]+c[i][1]-a[1][1]-a[1][j]-a[i][1]-a[i][j]);
    	}
	}
	cout<<ans+100;
	return 0;
} 

3.删数(delnum)

1.题目:

在这里插入图片描述
在这里插入图片描述

2.开始代码:

#include<bits/stdc++.h>
using namespace std;
int a[100001];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int ans;
	cin>>ans;
	for(int i=1;i<=ans;i++){
		int x;
		cin>>x;
		cout<<x/5-1<<endl;
	}
	return 0;
} 

直接靠运气,没有任何思路,推了推样例,第一个除了5,整除,第二个答案60%是除以5在减1,所以就试了试,直接崩了。

3.正解

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,del[100005];
int q,x;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&del[i]);
	scanf("%d",&q);
	while(q--){
		scanf("%d",&x);
		int cnt=0,f=0;
		for(int i=n;i>=1;i--){
			if(del[i]<=x){
				cnt+=(x-del[i])/i;
				x=del[i]+(x-del[i])%i;
				if(del[i]<x){
					cnt++;
					x-=i;
				}
				if(x==del[i]){
					f=1;
					break;
				}
			}
		}
		if(f) printf("%d\n",cnt+1);
		else printf("0\n");
	}
	return 0;
} 

就是从前往后推,删除前N小的数字,直到删了那个数字,从后往前删。

4.平分糖果(candy)

1.题目:

在这里插入图片描述

2.开始代码:

#include<bits/stdc++.h>
using namespace std;
int c;//记录局数 
int d[200005];
#define endl "\n"
int main() {
    int a[6];
    while (true) {
        cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]>>a[5];
        if (a[0]==0&&a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0) {//stop
            break;
        }
        c++;
        int t=0;//总美味程度
        for (int i=0;i<6;++i) {
            t+=a[i]*(i+1);//i+1为当前甜度 
        }
        // 如果总和为奇数,直接输出 Can't be divided.
        if (t%2!=0) {
            cout<<"Collection #"<<c<<":"<<endl<<"Can't be divided."<<endl;
            cout<<endl;
            continue;
        }
        //总和为偶数
        else{
        	int ta=t/2;
        // 	vector<bool> d(ta+1,false);
        	d[0]=true; //0美可以通过不选任何糖果获得
        	for (int i=0;i<6;++i){
            	if (a[i]>0){
                	for (int j=ta;j>=(i+1);--j){
                    	for (int k=1;k<=a[i]&&k*(i+1)<=j;++k){//k为个数 
                        	if(d[j-k*(i+1)]){
                            	d[j]=true;
                        	}
                    	}
                	}
            	}
        	}
        	if(d[ta]) {
            	cout<<"Collection #"<<c<<":"<<endl<<"Can be divided."<<endl;
        	}
			else{
            	cout<<"Collection #"<<c<< ":"<<endl<<"Can't be divided."<<endl;
        	}
        	cout<<endl;
		}
    }
    return 0;
}

思路:因为是平分,所以奇数个数的糖果一定不能平分,直接过掉。
剩下的情况就是偶数的情况:
以t为一半分,算出两边相同的甜度相同的值ta。
用d数组判断可不可以匹配。如果一直匹配到ta一直为true的话,那么就成立
中间的那个循环就是在平分两边的甜度

3.正解:

#include<bits/stdc++.h>
using namespace std;
long long a[7],m,dp[7][100001],cnt;
int main(){
	while(1){
		m=0;
		for(int i=1;i<=6;i++){
			cin>>a[i];
			m+=a[i]*i;
		}
		if(!m) break;
		cout<<"Collection #"<<++cnt<<":"<<endl;
		dp[0][0]=1;
		for(int i=1;i<=6;i++){
			for(int j=0;j<=a[i];j++){
				for(int k=j*i;k<=m/2;k++){
					dp[i][k]|=dp[i-1][k-j*i];
				}
			}
		}
		if(m%2==0&&dp[6][m/2]==1){
		    cout<<"Can be divided."<<endl<<endl;
		}
		else{
			cout<<"Can't be divided."<<endl<<endl;
		}
	}
	return 0;
} 

总结:

时间上还是有点问题,有些地方还是想不到小的细节,数据范围出了问题,少开了一位数,直接分数就下来了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aaronleoesr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值