2024.3.10:
刷题失败:1125 子串与子列
现在找到3个解法,后续弄懂:
【PAT甲级、乙级2020冬季】7-5 子串与子列 Subsequence in Substring (25 分)
7-5 子串与子列 (25 分)【测试点分析】【PAT(乙级)2020年冬季考试】
2020年冬季PAT乙级题解(C语言)
2024.3.11:
弄明白了:【PAT甲级、乙级2020冬季】7-5 子串与子列 Subsequence in Substring (25 分)
过段时间复盘一下
2024.3.12:
重做1125 子串与子列
仿照:
【PAT甲级、乙级2020冬季】7-5 子串与子列 Subsequence in Substring (25 分)
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std ;
int main()
{
string S;
string P;
cin >> S >> P ;
int head_location[10005] = {0} ; // 用来存储与子列的头部相同的子串的起始下标
int head_num = 0 ;
for (int i=0; i<S.size(); i++)
{
// 找到并存储与子列的头部相同的子串的起始下标
if (S[i] == P[0])
{
head_location[head_num] = i ;
head_num ++ ;
}
}
int minlen = (S.size()-1) ;
int minindex = 0;
for(int i=0; i<head_num; i++) // 每一个子串的头
{
int cnt = 0 ;
for(int j=head_location[i]; j<S.size(); j++)
{
if(S[j] == P[cnt]) cnt ++ ; // 当cnt走到了子列P的尾部时,j也到达了子串的尾部
if (cnt == P.size())
{
if ((j- head_location[i]) < minlen) // j-i的值是子串的长度再减1
{
minlen = j - head_location[i];
minindex = head_location[i] ;
}
}
}
}
for(int i=minindex ; i<=(minindex+minlen); i++)
cout << S[i];
}
2024.3.18:
看懂了7-5 子串与子列 (25 分)【测试点分析】【PAT(乙级)2020年冬季考试】,之后再去复盘
2024.3.19:
重做了1125 子串与子列,根据7-5 子串与子列 (25 分)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std ;
int main()
{
char s[10005], p[10005] ;
memset(s, '\0', 10005) ;
memset(p, '\0', 10005) ;
cin >> s ;
cin >> p ;
int len1 = strlen(s) ; // s的长度
int len2 = strlen(p) ; // p的长度
int minhead=0, minlen = len1; // minhead用来存储最短字串的头,minlen用来存储最短子串的长
for(int i=0; i<=(len1-len2); i++)
{
if (s[i] == p[0])
{
int t = i ; // 把这个相等的位置给记下来
for(int j = 0; j<len2;)
{
if(s[i] == p[j])
{
i++; j++;
}
else
{
i++ ;
}
}
if(minlen > (i-t))
{
minlen = i-t ;
minhead = t ;
}
i = t ; // i重新归位
}
}
for(int i = minhead; i<(minhead+minlen); i++)
cout << s[i] ;
return 0 ;
}
2024.3.20:
看懂了2020年冬季PAT乙级题解(C语言)
2024.3.21:
参考2020年冬季PAT乙级题解(C语言),复盘1125 子串与子列
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std ;
int main()
{
char s[10008], p[10008] ;
memset(s, '\0', 10008) ;
memset(p, '\0', 10008) ;
cin >> s ;
cin >> p ;
int t = 0, k = 0,i,j ;
int minlen = strlen(s), minhead = 0;
int flag = 0 ;
while(1)
{
for(i=0; i<strlen(p); i++)
{
if (i == 0) // 如果是p的头
{
for(j = (k+t); j<strlen(s); j++)
{
if (s[j] == p[i])
{
t = j ;
k = 1 ;
break ;
}
}
}
else // 如果不是p的头
{
for(j++; j<strlen(s); j++)
if (s[j] == p[i]) break ;
}
if(j == strlen(s))break ;
}
if(j == strlen(s))break ;
int len = j - t + 1 ;
if(len < minlen)
{
minlen = len ;
minhead = t ;
}
}
for(int g = minhead; g < (minhead+minlen); g++)
cout << s[g] ;
}
2024.3.21:
水题1124 最近的斐波那契数
#include <stdio.h>
int F[100000005] = {0} ;
int main()
{
int flag = 0 ;
int length = 0 ;
int k1 = 0, k2 = 0 ;
F[0] = 0 ;
F[1] = 1 ;
int n ;
scanf("%d", &n) ;
for(int i = 0; i < 100000005; i++)
{
if (i >= 2) F[i] = F[i-2] + F[i-1] ;
k1 = F[i] ;
k2 = F[i-1] ;
if(n == F[i])
{
flag = 1 ;
break ;
}
if (n < F[i])
{
break ;
}
}
if (flag == 1)
{
printf("%d", k1) ;
}
else
{
if((k1 - n) >= (n - k2))
printf("%d", k2) ;
else
printf("%d", k1) ;
}
}
2024.3.22:
这个题1123 舍入,代码只达到了部分正确:
#include <stdio.h>
int n, length ;
void deal_case1(char number[], int dot) // 四舍五入
{
int value = number[dot+length+1] - '0' ;
if (value >= 5)
{
if(number[dot+length] == '9')
{
number[dot+length] = '0' ;
number[dot+length-1] += 1 ;
}
else
{
number[dot+length] += 1 ;
}
}
}
void deal_case2(char number[], int dot) // 截断
{
return ;
}
void deal_case3(char number[], int dot) // 四舍六入五成双
{
if (number[dot+length+1] >= '6') // 大于6就进位
{
if(number[dot+length] == '9')
{
number[dot+length] = '0' ;
number[dot+length-1] += 1 ;
}
else
{
number[dot+length] += 1 ;
}
}
else if (number[dot+length+1] == '5')
{
for(int i = (dot+length+2); i < strlen(number); i++) // 后一位是5的第一种情况。如果5后面还有其它非0尾数,则进位
if(number[i] != '0')
{
if(number[dot+length] == '9')
{
number[dot+length] = '0' ;
number[dot+length-1] += 1 ;
}
else
{
number[dot+length] += 1 ;
}
return ;
}
if((number[dot+length] == '1') || (number[dot+length] == '3') || (number[dot+length] == '5') || (number[dot+length] == '7'))
number[dot+length] += 1 ;
if(number[dot+length] == '9')
{
number[dot+length] = '0' ;
number[dot+length-1] += 1 ;
}
}
}
int main()
{
scanf("%d", &n) ;
scanf("%d", &length) ;
int conduct ;
char number[201] ;
memset(number, '\0', 201) ;
char c ;
for(int i=0; i<n; i++)
{
scanf("%d", &conduct) ;
scanf("%c", &c) ;
scanf("%s", &number) ;
int dot = 0 ; // 记录小数点的下标
for(int i=0; i<strlen(number); i++) // 寻找小数点下标
{
if (number[i] == '.')
{
dot = i ; break ;
}
}
if (conduct == 1) deal_case1(number, dot) ;
else if (conduct == 2) deal_case2(number, dot) ;
else if (conduct == 3) deal_case3(number, dot) ;
for(int i = (dot+1); i<=(dot+length); i++)
if(number[i] == '\0')number[i] = '0' ;
for(int i = (dot+length+1); i<strlen(number); i++)
number[i] = '\0' ;
printf("%s", number) ;
if (i < (n-1))printf("\n") ;
}
}
2024.04.02:
水题1122 找奇葩:
#include <stdio.h>
#define MAXLENGTH 10009
#define MAXSIZE 100008
int number[MAXLENGTH] = {0} ; // 存放正整数序列
int times[MAXSIZE] = {0} ; // 暂存出现次数
int main()
{
int n ;
char c ; // 用于抵消间隔
scanf("%d", &n) ;
for(int i=0; i<n; i++)
{
scanf("%c", &c) ;
scanf("%d", &number[i]) ;
times[number[i]] += 1 ;
}
for(int i=0; i<MAXSIZE; i++)
if((times[i]!=0) && (i%2 !=0) && (times[i]%2!=0))
{
printf("%d", i) ;
break ;
}
}
#include <string>
#include <iostream>
using namespace std ;
int N ;
char c; // 用于消除间隔
string number; // 暂存待测评数字
int ten_multiple(int n) // 用于求10的n次放
{
int end = 1 ;
for(int i=1; i<=n; i++)
end *= 10 ;
return end ;
}
int judge(string number)
{
if(number.length() == 1)
return 1 ;
for(int i=1; i<number.length(); i++)
{
int temperory = 0;
for(int j = i; j>=0; j--)
temperory += (number[j] - '0') * ten_multiple(i-j);
if (temperory % (i+1) != 0)
return 0 ;
}
return 1 ;
}
int main()
{
scanf("%d", &N) ;
for(int i=0; i<N; i++)
{
scanf("%c", &c) ;
cin >> number ;
if(i > 0) cout << endl ;
if(judge(number))
cout << "Yes" ;
else
cout << "No" ;
}
}
关于1123 舍入,已找到两位大佬的答案,以供日后参考:
1123 舍入 测试点
PAT(乙级)2020年冬季考试
2024.04.03:
水题1120 买地攻略
#include <iostream>
#include <cstdio>
using namespace std ;
int N,M;
int prices[10009] = {0} ;
int main()
{
int approach = 0 ;
char c; // 用于抵消间隔
scanf("%d%d", &N,&M) ;
for(int i=0; i<N; i++)
{
scanf("%c", &c) ;
scanf("%d", &prices[i]);
}
for(int i=0; i<N; i++)
{
if(prices[i] <= M)
{
int temporary = prices[i] ;
approach++ ;
for(int j=(i+1); j<N; j++)
{
temporary += prices[j] ;
if(temporary <= M) approach++ ;
else break ;
}
}
else
{
continue ;
}
}
printf("%d\n", approach) ;
}
2024.04.03:
水题1119 胖达与盆盆奶
#include <stdio.h>
int N;
int Weight[10007] = {0} ;
int Mike[10007] = {0} ;
int main()
{
char c ; // 用于抵消换行和间隔
scanf("%d", &N) ;
for(int i=0; i<N; i++)
{
scanf("%c", &c) ;
scanf("%d", &Weight[i]);
Mike[i] = 200 ;
}
// 从头到尾检查一次
for(int j = (N-2); j >= 0; j--)
{
if(Weight[j] > Weight[j+1])
{
while(Mike[j] <= Mike[j+1])
Mike[j] += 100 ;
}
else if(Weight[j] == Weight[j+1])
{
while(Mike[j] < Mike[j+1])
Mike[j] += 100 ;
}
}
// 再从头到尾检查一次
for(int j = 1; j <= (N-1); j++)
{
if(Weight[j] > Weight[j-1])
{
while(Mike[j] <= Mike[j-1])
Mike[j] += 100 ;
}
else if(Weight[j] == Weight[j-1])
{
while(Mike[j] < Mike[j-1])
Mike[j] += 100 ;
}
}
int end = 0 ;
for(int i=0; i<N; i++)
end += Mike[i];
printf("%d\n", end) ;
}