CSP-J模拟赛四补题报告

5 篇文章 0 订阅
4 篇文章 0 订阅

前言

T1: 100 p t s \color{green}100pts 100pts

T2: 100 p t s \color{green}100pts 100pts

T3: 20 p t s → 5 p t s \color{red}20pts\rightarrow5pts 20pts5pts

T4: 20 p t s \color{red}20pts 20pts

T1,2秒了,T3,4死了

T1 三个(three)

题面

时间限制:1秒 内存限制:256M

1.1 问题描述

现在科学家在培养
A , B , C A,B,C A,B,C 三种微生物,这三种微生物每一秒都会繁殖出新的微生物,具体规则为:

A 类微生物每一秒会繁殖出 1 个 A A A 类微生物,1 个 B B B 类微生物,1 个 C C C 类微生物。

B B B 类微生物每一秒会繁殖出 2 个 A A A 类微生物, 2 2 2 C C C 类微生物。

C 类微生物每一秒会繁殖出 1 个 A A A 类微生物,1 个 B B B 类微生物。

假设所有的微生物都不会死亡,一开始培养皿中有 A , B , C A,B,C A,B,C 三种微生物各 1个,现在问你 n n n 秒后 A , B , C A,B,C A,B,C 三种微生物分别有奇数个还是偶数个。

1.2 输入格式

从文件 three.in 中读取数据。

一行一个整数 n n n

1.3 输出格式

输出到文件 three.out 中。

输出总共三行:

第一行:若 n n n 秒后 A A A 类微生物有奇数个,输出 odd,否则输出 even。
第二行:若 n n n 秒后 B B B 类微生物有奇数个,输出 odd,否则输出 even。
第三行:若 n n n 秒后 C C C 类微生物有奇数个,输出 odd,否则输出 even。

1.4 输入样例1

3

1.5 输出样例1

odd
odd
odd

1.6 输入样例2

4

1.7 输出样例2

odd
odd
even

1.8 输入样例3

233

1.9 输出样例3

even
even
odd

1.10 数据描述

总共 20 个测试点:

对于测试点 1∼4: 1 ≤ n ≤ 3 1≤n≤3 1n3
对于测试点 5∼8: 1 ≤ n ≤ 100 1≤n≤100 1n100
对于测试点 9∼20: 1 ≤ n ≤ 1 0 6 1≤n≤10^6 1n106
​​

思路

秒了

AC Code:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	freopen("three.in","r",stdin);
	freopen("three.out","w",stdout);
	long long a=1,b=1,c=1,n;
	scanf("%lld",&n);
	for(int i=1;i<=n;++i)
	{
		int A=a+a+2*b+c;
		int B=b+a+c;
		int C=c+a+2*b;
		a=A;
		b=B;
		c=C;
	}
	if(a%2==0)
	{
		printf("even\n"); 
	}
	else
	{
		printf("odd\n");
	}
	if(b%2==0)
	{
		printf("even\n");
	}
	else
	{
		printf("odd\n");
	}
	if(c%2==0)
	{
		printf("even\n");
	}
	else
	{
		printf("odd\n");
	}
	return 0;
} 

T2 合体(fit)

题面

时间限制:1秒 内存限制:256M

2.1 问题描述

现在有 n n n 个大小范围在 1 ∼ m 1∼m 1m 中的整数 a 1 ​​ ∼ a n a_1​​ ∼a_n a1​​an,并且你获得了一项魔法能力。

施加一次魔法能力后,可以将两个相同的数字合并成一个数字,并且这个数字为原来的数字 +1,例如:

有 2,2 这两个数字,施加一次魔法能力后可以将这两个数字合并成一个数字 3。

现在有 q q q 次询问,每次询问给你一个整数 x x x,你可以施加任意次数魔法能力,问你这 n n n 个整数最多能得到多少个整数 x x x

2.2 输入格式

从文件 fit.in 中读取数据。

第一行两个整数 n , m n,m n,m

第二行 n n n 个整数 a 1 ∼ a ​ n a_1∼a​_n a1an

第三行一个整数 q q q

接下来 q q q 行,每行一个整数 x x x

2.3 输出格式

输出到文件 fit.out 中。

输出 q q q 行,对于每个询问,输出对应的答案。

2.4 输入样例

10 4
1 1 1 2 1 3 4 1 2 3
5
1
2
3
4
4

2.5 输出样例

5
4
4
3
3

2.6 数据描述

总共 20 个测试点:

对于测试点 1∼4: 1 ≤ n ≤ 10 , 1 ≤ m ≤ 10 , 1 ≤ a ​ i ≤ m , 1 ≤ q ≤ 10 , 1 ≤ x ≤ m 1≤n≤10,1≤m≤10,1≤a_​i≤m,1≤q≤10,1≤x≤m 1n10,1m10,1aim,1q10,1xm

对于测试点 5∼6: 1 ≤ n ≤ 1 0 6 , m = 1 , a i = 1 , q = 1 , x = 1 1≤n≤10^6,m=1,a_i=1,q=1,x=1 1n106,m=1,ai=1,q=1,x=1

对于测试点7∼8: 1 ≤ n ≤ 1 0 6 , m = 5 , 1 ≤ a ​ i ≤ m , 1 ≤ x ≤ m 1≤n≤10^6,m=5,1≤a​_i ≤m,1≤x≤m 1n106,m=5,1aim,1xm

对于测试点 9∼20: 1 ≤ n ≤ 1 0 6 , 1 ≤ m ≤ 1 0 6 , 1 ≤ a ​ i ≤ m , 1 ≤ x ≤ m 1≤n≤10^6,1≤m≤10^6 ,1≤a​_i ≤m,1≤x≤m 1n106,1m106,1aim,1xm

思路

离线,秒了

AC Code:

#include<bits/stdc++.h>
using namespace std;
int a[1000005],ans[1000005],n,m; 
int main()
{
	freopen("fit.in","r",stdin);
	freopen("fit.out","w",stdout);
	int n,m,q,x;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		int t; 
		scanf("%d",&t);
		a[t]++;
	}
	for(int i=1;i<=m;i++)
	{
		ans[i]=a[i];
		a[i+1]+=a[i]/2;
	}
	scanf("%d",&q);
	while(q--)
	{
		scanf("%d",&x);
		printf("%d\n",ans[x]);
	}
	return 0;
}

矩阵(matrix)

思路

时间限制:2秒 内存限制:256M

3.1 问题描述

现在给你一个 n n n m m m 列的矩阵,矩阵上每个格子有一个整数,其中第 i i i 行第 j j j 列对应的格子上的整数为 g i , j g_{i,j} gi,j

现在定义该矩阵的一个子矩阵的快乐值为该子矩阵上的所有数字的异或和。

现在问你,该矩阵的所有子矩阵的快乐值之和为多少?

3.2 输入格式

从文件 matrix.in 中读取数据。

第一行两个整数 n , m n,m n,m
接下来 n n n 行,每行 m m m 个整数,表示该矩阵。

3.3 输出格式

输出到文件 matrix.out 中。

一行一个整数,表示答案。

3.4 输入样例

5 4
3 2 1 2
3 3 5 5
8 7 3 6
1 1 1 1
2 3 9 9

3.5 输出样例

822

3.6 数据描述

总共 20 个测试点:
对于测试点 1∼4: 1 ≤ n , m ≤ 10 , 0 ≤ g ​ i , j < 2 ​ 10 1≤n,m≤10,0≤g_{​i,j}<2^{​10} 1n,m10,0gi,j<2​10

对于测试点 5∼6: 1 ≤ n , m ≤ 300 , g ​ i , j = 1 1≤n,m≤300,g_{​i,j} =1 1n,m300,gi,j=1

对于测试点 7∼12: 1 ≤ n , m ≤ 300 , 0 ≤ g ​ i , j ​​ ≤ 1 1≤n,m≤300,0≤g_{​i,j}​​ ≤1 1n,m300,0gi,j​​1

对于测试点 13∼20: 1 ≤ n , m ≤ 300 , 0 ≤ g ​ i , j ​​ < 2 10 1≤n,m≤300,0≤g_{​i,j}​​ <2^{10} 1n,m300,0gi,j​​<210
​​

思路

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=305;
int n,m,a[N][N],b[N],sum[N];
long long ans;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	for(int u=1;u<=n;u++)
	{
		memset(b,0,sizeof(b));
		for(int d=u;d<=n;d++)
		{
			for(int j=1;j<=m;j++)
			{
				b[j]^=a[d][j];
				sum[j]=sum[j-1]^b[j];
			}
			for(int p=0;p<10;p++)
			{
				long long cnt[2]={1,0};
				for(int j=1;j<=m;j++)
				{
					int t=(sum[j]>>p)&1;
					ans+=(1<<p)*cnt[t^1];
					cnt[t]++; 
				}
			}
		}
	}
	printf("%lld",ans);
	return 0;
} 

数对(pair)

时间限制:2秒 内存限制:256M

4.1 问题描述

给你一个长度为 n n n 的数列 a ​ 1 , a ​ 2 ​​ , . . . , a n a​_1 ,a​_2​​ ,...,a_n a1,a2​​,...,an​​ 。

再给你一个长度为 m m m 的数列 b 1 , b 2 , . . . , b m b_1,b_2 ,...,b_m b1,b2,...,bm

现在再再再给你一个正整数 p p p,让你生成一个长度为 n × m n×m n×m 的数列 c 1 ​​ , c ​ 2 , . . . , c ​ n × m c_1​​ ,c​_2,...,c​_{n×m} c1​​,c2,...,cn×m

其中满足 c ( i − 1 ) × m + j = ( a i + b j ) m o d    p c(i−1)×m+j=(a_i+b_j)\mod p c(i1)×m+j=(ai+bj)modp

现在问你数列 c c c 中有多少个数对 ( i , j ) (i,j) (i,j)满足 i < j i<j i<j c i > c j c_i>c_j ci>cj

4.2 输入格式

从文件 pair.in 中读取数据。

第一行两个整数 n , m , p n,m,p n,m,p

第二行 n n n 个整数,表示 a ​ 1 ∼ a ​ n a​_1 ∼a​_n a1an

第三行 m 个整数,表示 b ​ 1 ∼ b ​ m b​_1∼b​_m b1bm

4.3 输出格式

输出到文件 pair.out 中。

一行一个整数,表示答案。

4.4 输入样例

6 7 10
1 1 4 5 1 4
1 9 1 9 8 1 0

4.5 输出样例

294

4.6 数据描述

总共 20 个测试点:

对于测试点 1∼4: 1 ≤ n , m ≤ 100 , 1 ≤ p ≤ 10 , 0 ≤ a i , b i < p 1≤n,m≤100,1≤p≤10,0≤a_i,b_i<p 1n,m100,1p10,0ai,bi<p

对于测试点 5∼6: 1 ≤ n , m ≤ 1000 , 1 ≤ p ≤ 10 , 0 ≤ a i , b ​ i ​​ < p 1≤n,m≤1000,1≤p≤10,0≤a_i,b​_i​​ <p 1n,m1000,1p10,0ai,bi​​<p

对于测试点 7∼8: 1 ≤ n , m ≤ 1000000 , p = 2 , 0 ≤ a i ​​ , b ​ i < p 1≤n,m≤1000000,p=2,0≤a_i​​ ,b​_i<p 1n,m1000000,p=2,0ai​​,bi<p

对于测试点 9∼20: 1 ≤ n , m ≤ 1000000 , 1 ≤ p ≤ 10 , 0 ≤ a ​ i , b ​ i < p 1≤n,m≤1000000,1≤p≤10,0≤a​_i,b​_i<p 1n,m1000000,1p10,0ai,bi<p

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,p,a[N],b[N];
long long cntb[15],res[15],vis[15];
void write(__int128 x)
{
	if(x>9)
	{
		write(x/10);
	}
	putchar(char(x%10+'0'));
}
int main()
{
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
		cntb[b[i]]++;
	}
	for(int k=0;k<p;k++)
	{
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=m;i++)
		{
			for(int j=b[i]+1;j<p;j++)
			{
				res[k]+=vis[j];
			}
			vis[b[i]]++;
			b[i]=(b[i]+1)%p;
		}
	}
	__int128 ans=0;
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++)
	{
		ans+=res[a[i]];
		for(int k=0;k<p;k++)
		{
			for(int j=(a[i]+k)%p+1;j<p;j++)
			{
				ans+=cntb[k]*vis[j];
			}
		}
		for(int k=0;k<p;k++)
		{
			vis[(a[i]+k)%p]+=cntb[k];
		}
	}
	write(ans);
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值