P5594 【XR-4】模拟赛
解题思路
- 重点是怎么判断是不是同一套模拟题
- 用一个数组来标记是不是同一套题
代码实现
#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 普及组] 统计单词数
解题思路
- 注意两个要求,第一个是完全匹配,第二个是不区分大小写
- 对于第一个要求,我们只要暴力每一个位置就可以了,然后判断是不是两个位置都符合要求
- 对于第二个要求,我们可以把所有的大写字母转换乘小写字母
代码实现
#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;
}
出错点
- 这个是有空格的所以不能使用kmp算法,而且这个还是要求完全匹配的
- 这个要完全匹配
P2010 [NOIP2016 普及组] 回文日期
解题思路
- 用循环来模拟每一天再判断组成的数是不是会文
#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;
}
出错点
- 要考虑结束年月份中可能在同一个月结束,那么就会多算一些天进去,因此要判断