CoduckCSP-J入门级复赛模拟2补题

一、题面

【T1】下棋(chess)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
请添加图片描述

【T2】汪洋(BigWater)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
请添加图片描述

【T3】删数(delnum)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
请添加图片描述

【T4】平分糖果(candy)

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

二、考试过程

考试经历

【T1】下棋(chess)

第一题考试觉得很简单(不过差点输入错误,幸亏检查出来了,差点爆0),没注意数据大小,未开long long

【T2】汪洋(BigWater)

看到这个题第一时间没看数据,结果写了个DFS,但是可能有小问题,没有拿分,后来一想前缀和确实能解决

【T3】删数(delnum)

没有思路,三层暴力,极限20分	

【T4】平分糖果(candy)

没有思路,直接骗分,极限15分

考试思路

【T1】下棋(chess)

结构体做,正常模拟(但要注意开long long)

【T2】汪洋(BigWater)

这是个图,用DFS做(但没做对且时间超限)

【T3】删数(delnum)

三层暴力循环(but时间超限)

【T4】平分糖果(candy)

没思路,骗分(或者说用特殊情况完成部分分获取)

三、考试源代码

			  给大家看看蒟蒻的考试代码
//chess
#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
	int a,b,c,id,sum;
}ch[100010];
bool cmp(node x,node y)
{
	if(x.sum==y.sum) return x.id<y.id;
	return x.sum>y.sum;
}
int main()
{
//	freopen("chess.in","r",stdin);
//	freopen("chess.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%d",&ch[i].c,&ch[i].b,&ch[i].a);
		ch[i].id=i;
		ch[i].b+=ch[i].c/3;
		ch[i].c%=3;
		ch[i].a+=ch[i].b/3;
		ch[i].b%=3;
		ch[i].sum=18*ch[i].a+3*ch[i].b+ch[i].c;
	}
	sort(ch+1,ch+n+1,cmp);
	for(int i=1;i<=n;i++)
		printf("%d ",ch[i].id);
	return 0;
}
//BigWater
#include<bits/stdc++.h>
using namespace std;
int n,ans;
int a[1010][1010];
int dx[]={0,0,1,-1};
int dy[]={-1,1,0,0};
bool vis[1010][1010];
void dfs(int x,int y,int k,int sum)
{
	
	if(vis[x][y]||x>n||x<1||y>n||y<1) return;
	if(x==2&&y==1){
		if(k==2||k==3)
			ans=max(ans,sum);
		return;
	}
	vis[x][y]=1;
	int sx=x+dx[k];
	int sy=y+dy[k];
	dfs(sx,sy,k,sum+a[sx][sy]);
	sx=x+dx[(k+1)%4];
	sy=y+dy[(k+1)%4];
	dfs(sx,sy,(k+1)%4,sum+a[sx][sy]);
	vis[x][y]=0;
}
int main()
{
//	freopen("BigWater.in","r",stdin);
//	freopen("BigWater.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	dfs(1,1,0,100);
	printf("%d",ans);
	return 0;
}
/*5
0 -3 8 -2 3 
3 -1 -3 -10 -6
9 -9 -6 10 -7
-2 -4 -9 6 -10 
-1 8 -7 10 -5*/
//delnum
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
int n,a[N],q,x,c[1000010];
int vis[N];
int b[N];
void fun(int x)
{
	for(int i=1;i<=n;i++) b[i]=a[i];
	for(int i=1;i<=x/n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			int cnt=0;
			for(int k=1;k<=x;k++)
			{
				if(vis[k]==0)
					cnt++;
				if(cnt==a[j])
				{
					b[j]=k;
					break;
				}
			}
			
		}
		for(int j=1;j<=n;j++) vis[b[j]]=i;
	}
	
}
int main()
{
//	freopen("delnum.in","r",stdin);
//	freopen("delnum.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d",&q);
	fun(5100);
	while(q--)
	{
		scanf("%d",&x);
		printf("%d\n",vis[x]);
	} 
	return 0;
}
//平分糖果
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
int a[6];
int cnt,g[N];
bool dfs(int len,int x)
{
	for(int i=x;i<=cnt;i++)
	{
		if(len<a[i]) return 0;
		if(dfs(len-a[i],i+1)) return 1;
	}
}
int main()
{
//	freopen("candy.in","r",stdin);
//	freopen("candy.out","w",stdout);
	int pos=0;
	while(1)
	{
		bool flag=0;
		long long sum=0;
		for(int i=1;i<=6;i++)
		{
			scanf("%d",a+i);
			if(a[i]) flag=1;
			sum+=a[i]*i;
			for(int j=1;j<=a[i];j++)
			{
				g[+cnt]=i;
			}
		}
		if(!flag) break;
		pos++;
		printf("Collection #%d:\n",pos);
		if(dfs(sum/2,1)||sum%2!=0) printf("Can be divided.\n\n");
		else printf("Can't be divided.\n\n");
	}
	return 0;
}

四、思路讲解

【T1】用结构体模拟,直接根据题目模拟机即可(注意开long long)
【T2】用两个一维前缀和或两个二维前缀和计算每个点(注意最后要回到(1,1)的位置上)
【T3】当x小于a[]的最大值时,每次删数会让a[]缩小n,当小于最大值时,会缩小n-比x大的a[]数
【T4】二进制优化多重背包

五、AC代码

		           接下来是AC代码 
//chess
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
struct node{
	int a,b,c,id,sum;
}ch[100010];
bool cmp(node x,node y)
{
	if(x.sum==y.sum) return x.id<y.id;
	return x.sum>y.sum;
}
signed main()
{
//	freopen("chess.in","r",stdin);
//	freopen("chess.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%d",&ch[i].c,&ch[i].b,&ch[i].a);
		ch[i].id=i;
		ch[i].b+=ch[i].c/3;
		ch[i].c%=3;
		ch[i].a+=ch[i].b/3;
		ch[i].b%=3;
		ch[i].sum=18*ch[i].a+3*ch[i].b+ch[i].c;
	}
	sort(ch+1,ch+n+1,cmp);
	for(int i=1;i<=n;i++)
		printf("%d ",ch[i].id);
	return 0;
}
//BigWater
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1005;
int n,a[N][N],r[N][N],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;
}
//delnum
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+100;
int n,a[N],q,x;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d",&q);
	while(q--)
	{
		scanf("%d",&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) printf("%d\n",ans);
		else puts("0");
	}
	return 0;
}
//candy
#include<bits/stdc++.h>
using namespace std;
const int N=1.2e5+100;
int mark,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");
	}
	return 0;
}

六、写在最后

1.写给过去的自己:

                     普及组也还行

2.写给现在的自己:

                       还要努力

3.写给未来的自己:

				   普及正式考试加油
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值