2024年2月20号题解

P5594 【XR-4】模拟赛

解题思路

  1. 重点是怎么判断是不是同一套模拟题
  2. 用一个数组来标记是不是同一套题

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 1001

int n, m, k;
int a[N][N];
int ans[N];

int main(int argc, char* argv[])
{
	sc("%d%d%d", &n, &m, &k);
	
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= m; j ++) {
			sc("%d", a[i] + j);
		}
	}
	
	for (int i = 1; i <= m; i ++) {
		bool v[N] = {0};//用来标记 
		for (int j = 1; j <= n; j ++) {
			if (!v[a[j][i]]) {//如果之前没有访问过,代表要增加一场考试 
				ans[a[j][i]] ++;//对应的天数加一 
			}
			v[a[j][i]] = 1;//访问过之后就标记已经访问了 
		}
	}
	
	//打印答案 
	for (int i = 1; i <= k; i ++) {
		pr("%d ", ans[i]);
	}
	
	return 0;
}

P1308 [NOIP2011 普及组] 统计单词数

解题思路

  1. 注意两个要求,第一个是完全匹配,第二个是不区分大小写
  2. 对于第一个要求,我们只要暴力每一个位置就可以了,然后判断是不是两个位置都符合要求
  3. 对于第二个要求,我们可以把所有的大写字母转换乘小写字母

代码实现

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 1000001

char s1[11];
char s2[N];
int len;//s1的长度 
int size;//s2的长度 
int ans;//记录单词出现的次数 
int first = -1;//记录第一个完全匹配的单词位置 

int main(int argc, char* argv[])
{
	gets(s1);//读入需要匹配的单词 
	gets(s2);//因为字符串中有空格,所以需要用gets 

	len = strlen(s2);//计算s1的长度 
	size = strlen(s1);//计算s2的长度 

	for (int i = 0; i < len; i++) {//把s2中的大写字母转换成小写字母 
		if (s2[i] >= 'A' && s2[i] <= 'Z') {
			s2[i] += 32;
		}
	}

	for (int i = 0; i < size; i++) {//把s1中的大写字母转换成小写字母 
		if (s1[i] >= 'A' && s1[i] <= 'Z') {
			s1[i] += 32;
		}
	}

	for (int i = 0; i < len; i++) {//遍历每一个位置看有没有单词可以匹配 
		if (i == 0) {//把第一个位置单独拿出来,因为第一个位置不可能有空格, 
			int j, k;
			for (j = 0, k = i; j < size; ) {//与s1的每一个比较 
				if (s1[j] == s2[k]) {//相同就下一个位置 
					j++;
					k++;
				}
				else {//不同就跳出代表不匹配 
					break;
				}
			}
			if (j == size && s2[k] == ' ') {//完全匹配 
				ans++;
			}
			if (j == size && s2[k] == ' ' && first == -1) {//第一次完全匹配 
				first = i;
			}
		}
		else {//不是第一个位置
			if (s2[i - 1] == ' ') {//如果前面是空格,那么就可以完全匹配 
				int j, k;
				for (j = 0, k = i; j < size; ) {
					if (s1[j] == s2[k]) {
						j++;
						k++;
					}
					else {
						break;
					}
				}
				if (j == size && s2[k] == ' ') {//完全匹配 
					ans++;
				}
				if (j == size && s2[k] == ' ' && first == -1) {//第一次完全匹配 
					first = i;
				}
			}
		}
	}

	if (ans != 0)//如果一次都没有出现过 
		pr("%d %d", ans, first);
	else {
		pr("-1");
	}

	return 0;
}

出错点

  1. 这个是有空格的所以不能使用kmp算法,而且这个还是要求完全匹配的
  2. 这个要完全匹配

P2010 [NOIP2016 普及组] 回文日期

解题思路

  1. 用循环来模拟每一天再判断组成的数是不是会文
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 10

int day[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int ans;

bool isy(int y) {
	if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) {
		return true;
	}

	return false;
}

bool f(int n) {
	int ans = 0;
	int t = n;

	while (t) {
		ans = ans * 10 + t % 10;
		t /= 10;
	}

	return n == ans;
}

int main(int argc, char* argv[])
{
	int ay = 0;//开始的年份 
	int am = 0;//开始的月份 
	int ad = 0;//开始的天 
	int by = 0;//结束的年份 
	int bm = 0;//结束的月份 
	int bd = 0;//结束的日期

	sc("%4d%2d%2d%4d%2d%2d", &ay, &am, &ad, &by, &bm, &bd);

	for (int i = ay; i <= by; i++) {//模拟年份
		if (i == ay) {//如果是第一年
			for (int j = am; j <= 12; j++) {//模拟月份
				for (int k = 1; k <= ((ad < day[j]) ? ad : (isy(i) && j == 2 ? day[j] + 1 : day[j])); k++) {//模拟天数,但要注意结束的天数可能再同一个月,使用要特判
					int n = i * 10000 + j * 100 + k;//组合成一个8位数
					if (f(n)) {//判断是不是回文
						ans++;
					}
				}
			}
		}
		else {//不是第一年了
			for (int j = 1; j <= 12; j++) {//模拟月份
				for (int k = 1; k <= (isy(i) && j == 2 ? day[j] + 1 : day[j]); k++) {//模拟天数,这里不要特判,因为一定不是同一个月了
					int n = i * 10000 + j * 100 + k;//组合成一个8位数
					if (f(n)) {//判断是不是回文
						ans++;
					}
				}
			}
		}
	}

	pr("%d", ans);

	return 0;
}

出错点

  1. 要考虑结束年月份中可能在同一个月结束,那么就会多算一些天进去,因此要判断
posted @ 2024-02-20 20:34  lwj1239  阅读(27)  评论(0)    收藏  举报