ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CDZSC_2022寒假个人训练赛21级(9)题解

2022-02-15 17:00:48  阅读:131  来源: 互联网

标签:21 int 题解 CDZSC ++ ans -- include scanf


  • 简单
    • E 简单模拟
    • F 模拟
  • 中等
    • A 瞎搞,预处理
    • B 打表瞎搞
    • G
    • H 贪心
    • D 简单模拟
  • 困难
    • C 瞎搞,思维
    • I 枚举

A Memory Management System Gym - 102152B

题意

给你一个\(m\)长的空间,其间有部分空间已被\(n\)个\(l_i—r_i\)长的文件占据。现给出\(q\)个新文件的大小\(x_j\),试找到能放下\(x_j\)的空县连续空间(满足\(r_j\)最大的同时\(l_j\)也最大);如果没有能放下\(x_j\)长度新文件的空现空间,便输出-1。

题解

这题方法很多

  • 方法一是先处理给定的序列,然后把所有答案打表出来,处理询问的时候直接输出对应答案就好。
  • 方法二,我两年前写的代码,有兴趣的可以领会一下。

AC代码

//方法一
#include <iostream>
#include <algorithm>
#include <cmath>
#include<ctime>
#include <cstring>
using namespace std;
typedef long long ll;

int s[100005];
int ansl[100005], ansr[100005];
int main() {
	int t, n, m, q,x;
	scanf("%d", &t);
	while (t--) {
		int o = 0;
		scanf("%d%d%d", &n, &m, &q);
		for (int i = 1; i <= m; i++) {
			ansl[i]=ansr[i]=s[i] = -1;
		}
		for (int i = 0; i < n; i++) {
			int l, r;
			scanf("%d%d", &l, &r);
			for (int j = l; j <= r; j++)s[j] = 0;
		}
		int len = 0,last=0;
		for (int i = m; i > 0; i--) {
			if (s[i]) {
				if (last==0) {
					last = i;
				}
				len++;
			}
			else if(last){
				last = len = 0;
			}
			if (last&&ansl[len]==-1) {
				ansl[len] = i;
				ansr[len] = last;
			}
		}
		while (q--) {
			scanf("%d", &x);
			printf("%d %d\n", ansl[x], ansr[x]);
		}
		
	}
}
//方法二
#include<iostream>

using namespace std;
int s[100005];
int sy[100000];
int cl[100000];
int main() {
	int t, n, m, q;
	scanf("%d", &t);
	while (t--) {
		int o = 0;
		scanf("%d%d%d", &n, &m, &q);
		s[0] = s[m + 1] = 0;
		for (int i = 1; i <= m; i++) {
			s[i] = -1;
			sy[i] = 0;
		}
		for (int i = 0; i < n; i++) {
			int l, r;
			scanf("%d%d", &l, &r);
			for (int j = l; j <= r; j++)s[j] = 0;
		}

		for (int i = 1, j; i <= m;) {
			for (; s[i] == 0; i++);
			if (i > m)break;
			for (j = 0; s[i]; i++)j++;
			for (; j; j--)sy[j] = i - 1;
		}
		for (int i = 0; i < q; i++) {
			int k, x = -1, y = -1;
			scanf("%d", &k);
			if (sy[k]) {
				y = sy[k];
				x = y - k + 1;
			}
			printf("%d %d\n", x, y);
		}
		
	}



}

B Large GCD Gym - 102152C

题意

给定\(n,m\),求\(F(n,m)=gcd(5^n+7^n,5^m+7^m)\),保证\(gcd(n,m)≡1\)

题解

直接证明难度较大,但实际上打个表就知道规律了,很明显,有的时候学会猜答案也是很重要的。
证明:
我不会,大概就有公式

\[gcd(B^n+A^n,B^m+A^m)=B+(−1)^{m+n}A \]

还有一个类似的公式

\[gcd(B^n-A^n,B^m-A^m)= gcd(a^m−b^m,a^{n\;mod\;m}−b^{n\;mod\;m}) \]

\[即gcd(B^n-A^n,B^m-A^m)= B^{gcd(n,m)}-A^{gcd(n,m)} \]

有兴趣可以看以下证明
https://math.stackexchange.com/questions/262130/how-to-prove-gcdam-bm-an-bn-a-gcdm-n-b-gcdm-n
https://math.stackexchange.com/questions/1998803/let-m-and-n-be-positive-integers-such-that-gcdm-n-1-compute-gcd5m7

AC代码

#include<iostream>
#include <math.h>
using namespace std;
typedef long long ll;
int gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}


int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, m;
		scanf("%d%d", &n, &m);
		/*printf("%d\n", gcd(pow(5, n) + pow(7, n), pow(5, m) + pow(7, m)));*/
		if (n % 2 && m % 2) {
			printf("12\n");
		}
		else {
			printf("2\n");
		}

	}
    return 0;
}

C XOR Permutations Gym - 102152D

题意

给你三个十位的二进制数字,你可以任意改变他们的“0”和“1”的位置,求这三个二进制数字异或的最大值。

题解

实际上很简单,我难度给高是因为我们当时没人出,但我现在一看题目就差不多有答案了。
因为可以任意改“0”和“1”的位置,所以位置信息完全没用,我们只要知道3个二进制串中1的个数就好了,如果3个串中1的个数和少于等于10,那就直接错开排列,就有最多的1也就可以组成最大值。如果和大于10,那么我们为了使异或后1的数量增加,我们肯定要3个1一排,这样子他还是1,就帮助我们消除了多余的1了,比如12个1,我们可以1个3(3指3个1并排)+9个1,这样子的方法排列就有10个1达到最大,但问题是很多时候你不能3个1并排,比如这个样例
1111111111
0000000000
1111111111
中间那行一个1都没有,不论你其他行怎么排都没办法有3个1并列,所以我们加一个限制,就是3行中最少的1的数量,设a[i]为第i行的1的数量,限制就是min(a[1],a[2],a[3]),用这个方法把1消耗掉后,如果还是大于10,那就只能两两排了,两两排的答案是20-(剩余1的数量)。

给你们几组样例方便你们debug。

3
1111111111
0000000000
1111111111
1111111111
0000000000
1111111110
1111111111
1000000000
1111111110
0000000000
1000000000
1100000000

AC代码

#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;

int main(){
	int t;
	scanf("%d", &t);
	while (t--) {
		int a[3] = {0}, x;
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 10; j++) {
				scanf("%1d", &x);
				if (x)a[i]++;
			}
		}
		int ans = 0;
		int sum = a[0] + a[1] + a[2];
		int mn = min(a[0], min(a[1], a[2]));
		if ( sum<= 10) {
			ans =sum;
		}
		else {
			ans = sum;
			while (ans > 10 && mn) {
				mn--;
				ans -= 2;
			}
			if (ans > 10)ans = 20-ans ;
		}
		for (int i = 0; i < ans; i++)printf("1");
		for (int i = ans+1; i <= 10; i++)printf("0");
		printf("\n");
	}

	return 0;
}

D Building Strings Gym - 102152E

题意

给3个字符串s、c、p,c是由数字组成的,s和c对应,如得到一个s[i]字符的花费是c[i],问要构成字符串p,最小花费是多少,如果不能构成则输出-1。

题解

简单模拟

AC代码

#include<iostream>

using namespace std;
char s[2000],c[2000], p[2000];
int book[200];
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		for (int i = 0; i <= 200; i++)book[i] = 10;
		int n, m, sum = 0;
		scanf("%d%d", &n, &m);
		scanf("%s%s%s", s,c,p);

		for (int i = 0; i < n; i++) {
			if (book[s[i]]>c[i]-'0') 
				book[s[i]] = c[i] - '0';
		}
		for (int i = 0; i < m; i++) {
			if (book[p[i]] == 10) {
				sum = -1;
				break;
			}
			sum += book[p[i]];
		}
		printf("%d\n", sum);
	}

}

E camelCase; Gym - 102152F

题意

判断驼峰字符串是否在7词以内,保证给出的都是驼峰字符串。

题解

简单模拟

AC代码

#include<iostream>
#include<string.h>
using namespace std;
char s[200];
int main() {
	int t;
	scanf("%d", &t);
	while (t--){
		scanf("%s", s);
		int len = strlen(s);
		int sum = 1;
		for (int i = 0; i < len; i++) {
			if (s[i] <= 'Z') 
				sum++;
		}
		if (sum <= 7)printf("YES\n");
		else printf("NO\n");
	}


F The Universal String Gym - 102152H

题意

判断字符串是否是无限个“abcdefghijklmnopqrstuvwxyz”构成的字符串的子串。

题解

模拟

AC代码

#include<iostream>
#include<string.h>
using namespace std;

char x[2000];
int book[200];
int main() {
	int t;
	for (int i = 'a'; i < 'z'; i++) 
		book[i] = i+1;
	book['z'] = 'a';

	scanf("%d", &t);
	while (t--) {
		int flag = 1;
		scanf("%s", x);
		int len = strlen(x);
		for (int i = 0; i<len-1; i++) {
			if (x[i+1]!=book[x[i]])
				flag = 0;
		}
		if (flag)printf("YES\n");
		else printf("NO\n");
	}

}

G The Hell Boy Gym - 101532J

题意

给出数组的子集累乘的累和。

题解

高中数学,\((1+a)*(1+b)*(1+c)=1+a+b+c+ab+ac+bc+abc\)

AC代码

#include<iostream>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
int main() {
	int t, n;
	scanf("%d", &t);
	while (t--) {
		ll ans = 1,x;
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%lld", &x);
			ans =ans*(x + 1)%mod;
		}
		printf("%lld\n", (ans-1+mod)%mod);

	}
}

H Grid Beauty Gym - 102152J

题意

给你一个n*m的二维数组,你可以随意交换同行数字,问最大化的 the beauty of the grid 的值是多少, the beauty of the grid 定义是相邻行中相同的数字的对数。

题解

贪心,因为可以随意移动行,所以实际你只要贪心匹配就好,匹配第i行和第i-1行有几个相同的,累和起来就是答案了。

AC代码

#include<iostream>
#include<map>
using namespace std;
map<int, int> book[1005];
int main() {
	int t;
	scanf("%d", &t);
	while (t--){
		int n, m,sum=0,x;
		scanf("%d%d", &n, &m);	
		for(int i=1;i<=n;i++)book[i].clear();
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				scanf("%d",&x);
				if(book[i-1][x]){
					sum++;
					book[i-1][x]--;
				}
				book[i][x]++;
			}
		}
		printf("%d\n", sum);
	}
	return 0;
}

I Subarrays OR Gym - 102152K

题意

给你一个数组,问你这个数组的所有子数组的按位或总共能得到几种不同的数字。数据范围1e5。

题解

直接枚举加个优化,

if (l[j] == ans)break;
l[j] = ans;

这个的意思是在上一次循环的这个位置的累或相同,那么就直接跳出,因为后面要或上一样的值,既然目前值和后面要或上的值都相同,那就可以直接跳出了。
复杂度分析: 在最坏的情况下这种优化的复杂度,一种很坏的情况是,前几个数字的某个二进制位,后面的数字都没有,比如001 000 010 100 110 ,在第二次循环的时候由于后面的数字都没有1这个二进制位,所以都不能被这个方法优化,同样的0001 0010 0000 0100 1000 1100 ,第二和第三次循环都不能被优化,但很明显这种情况最坏是15次循环,因为数据范围1e9 大概有31位二进制位,数组长度1e5,大概是16个二进制位,所以说最多在前面构造出15个后面都没有的独立二进制位,所以复杂度最多也就15 * 1e5,1e6左右。实际上这种构造方法也是答案数最多的构造方法之一,最多的答案数也是15 * 1e5,1e6左右,所以可以直接枚举,并且使用set,set的复杂度是O(NlogN)综上所述,最终复杂度是O(NlogN),N为1e6左右。

AC代码

#include<iostream>
#include<set>
using namespace std;
int s[100005];
int l[100005];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		set<int>m;
		int n;
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%d", &s[i]);
			l[i]=-1;
		}
		for (int i = 0; i < n; i++) {
			int ans = 0;
			for (int j = i; j < n; j++) {
				ans |= s[j];
				m.insert(ans);
				if (l[j] == ans)break;
				l[j] = ans;
			}
		}
		printf("%d\n", m.size());

	}

}

标签:21,int,题解,CDZSC,++,ans,--,include,scanf
来源: https://www.cnblogs.com/komet/p/15897295.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有