01 特殊年份
问题描述
今年是2021年,2021这个数字非常特殊,它的千位和十位相等,个位比百位大1,我们称满足这样条件的年份为特殊年份。输入5个年份,请计算这里面有多少个特殊年份。
输入格式
输入5行,每行一个4位十进制数(数值范围为1000至9999),表示一个年份。
输出格式
输出一个整数,表示输入的5个年份中有多少个特殊年份。
样例输入
2019
2021
1920
2120
9899
样例输出
2
样例说明
2021和9899是特殊年份,其它不是特殊年份。
#include<bits/stdc++.h>
using namespace std;
int ans;
int main()
{
string s;
for(int i=1;i<=5;i++){
cin>>s;
if(s[0]==s[2]&&s[1]==s[3]-1){
ans++;
}
}
cout<<ans;
return 0;
}
02 次数差
题目描述
×星球有26只球队,分别用a~z的26个字母代表。他们总是不停地比赛。在某一赛段,哪个球队获胜了,就记录下代表它的字母,这样就形成一个长长的串。国王总是询问:获胜次数最多的和获胜次数最少的有多大差距?(当然,他不关心那些一次也没获胜的,认为他们在怠工罢了)
输入描述
输入,一个串,表示球队获胜情况(保证串的长度<1000)。
输出描述
要求输出一个数字,表示出现次数最多的字母比出现次数最少的字母多了多少次。
输入输出样例
示例
输入
abaabcaa
输出
4
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin >> str;
int arr[26] = {0};
for (int i = 0; i < (int)str.size(); i++)
arr[str[i] - 'a']++;
sort(arr, arr + 26);
for (int i = 0; i < 26; i++)
if (arr[i] != 0)
{
cout << arr[25]-arr[i] << endl;
break;
}
return 0;
}
03 车牌
问题描述
A市的车牌由六位组成,其中前三位可能为数字0至9,或者字母A至F,每位有16种可能。后三位只能是数字0至9。为了减少攀比,车牌中不能有连续三位是相同的字符。例如,202020是合法的车牌,AAA202不是合法的车牌,因为前三个字母相同。
请问,A市有多少个合法的车牌?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include <iostream>
using namespace std;
bool check(int a,int b,int c,int d,int e,int f){
if(a==b && b==c) return false;
if(b==c && c==d) return false;
if(c==d && d==e) return false;
if(d==e && e==f) return false;
return true;
}
int main()
{
// 请在此输入您的代码
int count=0;
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
for(int k=0;k<16;k++){
for(int x=0;x<10;x++){
for(int y=0;y<10;y++){
for(int z=0;z<10;z++){
if(check(i,j,k,x,y,z)){
count++;
}
}
}
}
}
}
}
cout << count <<endl;
return 0;
}
04 杨辉三角形
杨辉三角也叫帕斯卡三角,在很多数量关系中可以看到,十分重要。
第0行: 1
第1行: 1 1
第2行: 1 2 1
第3行: 1 3 3 1
第4行: 1 4 6 4 1
....
两边的元素都是1,中间的元素是左上角的元素与右上角的元素和。我们约定,行号,列号都从0计数。所以:第6行的第2个元素是15,第3个元素是20。直观地看,需要开辟一个二维数组,其实一维数组也可以胜任。如下程序就是用一维数组“腾挪”的解法。
请仔细分析源码,填写划线部分缺少的内容。
源代码
C
#include <stdio.h>
// 杨辉三角的第row行,第col列
long long f(int row, int col){
if(row<2) return 1;
if(col==0) return 1;
if(col==row) return 1;
long long a[1024];
a[0]=1;
a[1]=1;
int p = 2;
int q;
while(p<=row){
a[p] = 1;
for(_________________) a[q] = a[q] + a[q-1]; //填空
p++;
}
return a[col];
}
int main()
{
printf("%d\n", f(6,2));
printf("%d\n", f(6,3));
printf("%lld\n", f(40,20));
return 0;
}
Java
import java.util.Scanner;
public class Main
{
// 杨辉三角形的第row行第col列
static long f(int row, int col){
if(row<2) return 1;
if(col==0) return 1;
if(col==row) return 1;
long[] a = new long[row+1];
a[0]=1;
a[1]=1;
int p = 2;
while(p<=row){
a[p] = 1;
for( _________________ ) a[q] = a[q] + a[q-1];
p++;
}
return a[col];
}
public static void main(String[] args){
System.out.println(f(6,2));
System.out.println(f(6,3));
System.out.println(f(40,20));
}
}
#include <stdio.h>
// 杨辉三角的第row行,第col列
long long f(int row, int col){
if(row<2) return 1;
if(col==0) return 1;
if(col==row) return 1;
long long a[1024];
a[0]=1;
a[1]=1;
int p = 2;
int q;
while(p<=row){
a[p] = 1;
for(q=p-1;q;q--) a[q] = a[q] + a[q-1]; //填空
p++;
}
return a[col];
}
int main()
{
printf("%d\n", f(6,2));
printf("%d\n", f(6,3));
printf("%lld\n", f(40,20));
return 0;
}
05 隔行变色
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
Excel表的格子很多,为了避免把某行的数据和相邻行混淆,可以采用隔行变色的样式。
小明设计的样式为:第1行蓝色,第2行白色,第3行蓝色,第4行白色……
现在小明想知道,从第21行到第50行一共包含了多少个蓝色的行。
#include<stdio.h>
main()
{
int i,sum=0;
int a[51];
for(i=1;i<51;i++)
{
if(i%2==0)
a[i]=0;//白色
else
a[i]=1;//蓝色
}
for(i=21;i<51;i++)
{
if(a[i]==1)
sum++;
}
printf("%d",sum);
return 0;
}
06 Fibonacci 集合
问题描述
小蓝定义了一个Fibonacci集合F,集合的元素如下定义:
1.最小的5个Fibonacci数1,2,3,5,8属于集合F。
2.如果一个元素x属于F,则3x+2、5x+3和8x+5都属于集合F。
3.其他元素都不而于F。
请问,这个集合中的第2020小元素的值是多少?
答案提交
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include <iostream>
using namespace std;
long long f[2030];
int main()
{
int t1 = 0,t2 = 0,t3 = 0;
f[0] = 0;
for(int i = 1;i<=2020;i++){
f[i] = min(f[t1] * 3+2,min(f[t2] * 5+3,f[t3] * 8+5));
if(f[i] == f[t1] * 3+2 ) t1++;
if(f[i] == f[t2] * 5+3 ) t2++;
if(f[i] == f[t3] * 8+5 ) t3++;
}
cout << f[2019];
return 0;
}
07 最大公共子串
最大公共子串长度问题就是:求两个串的所有子串中能够匹配上的最大长度是多少。
比如:“abcdkkk"和"baabcdadabc”,可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。
下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
请分析该解法的思路,并补全划线部分缺失的代码。
源代码
C
#include <stdio.h>
#include <string.h>
#define N 256
int f(const char* s1, const char* s2)
{
int a[N][N];
int len1 = strlen(s1);
int len2 = strlen(s2);
int i,j;
memset(a,0,sizeof(int)*N*N);
int max = 0;
for(i=1; i<=len1; i++){
for(j=1; j<=len2; j++){
if(s1[i-1]==s2[j-1]) {
a[i][j] = __________________________;
if(a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
int main()
{
printf("%d\n", f("abcdkkk", "baabcdadabc"));
printf("%d\n", f("aaakkkabababa", "baabababcdadabc"));
printf("%d\n", f("abccbaacbcca", "ccccbbbbbaaaa"));
printf("%d\n", f("abcd", "xyz"));
printf("%d\n", f("ab", "ab"));
return 0;
}
Java
import java.util.Scanner;
public class Main
{
static int f(String s1, String s2)
{
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
int[][] a = new int[c1.length+1][c2.length+1];
int max = 0;
for(int i=1; i<a.length; i++){
for(int j=1; j<a[i].length; j++){
if(c1[i-1]==c2[j-1]) {
a[i][j] = __________________________;
if(a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
public static void main(String[] args){
int n = f("abcdkkk", "baabcdadabc");
System.out.println(n);
System.out.println(f("aaakkkabababa", "baabababcdadabc"));
System.out.println(f("abccbaacbcca", "ccccbbbbbaaaa"));
System.out.println(f("abcd", "xyz"));
System.out.println(f("ab", "ab"));
}
}
#include <stdio.h>
#include <string.h>
#define N 256
int f(const char* s1, const char* s2)
{
int a[N][N];
int len1 = strlen(s1);
int len2 = strlen(s2);
int i, j;
memset(a, 0, sizeof(int) * N * N);
int max = 0;
for (i = 1; i <= len1; i++) {
for (j = 1; j <= len2; j++) {
if (s1[i - 1] == s2[j - 1]) {
a[i][j] = a[i - 1][j - 1]+1;
if (a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
int main()
{
printf("%d\n", f("abcdkkk", "baabcdadabc"));
printf("%d\n", f("aaakkkabababa", "baabababcdadabc"));
printf("%d\n", f("abccbaacbcca", "ccccbbbbbaaaa"));
printf("%d\n", f("abcd", "xyz"));
printf("%d\n", f("ab", "ab"));
return 0;
}
08 凑算式
#include <iostream>
using namespace std;
int ans;
int a[] = {1,2,3,4,5,6,7,8,9};
bool check(int a[]){
int d = a[3]*100+a[4]*10+a[5];
int e = a[6]*100+a[7]*10+a[8];
if((a[1]*d+a[2]*e)%(a[2]*e) == 0 && a[0]+a[1]/a[2]+d/e == 10)
return true;
return false;
}
void f(int k){
if(k==9){
if(check(a)){
ans+=1;
return ;
}
}
for (int i = k; i < 9 ; ++i) {
{int t;t=a[i];a[i]=a[k];a[k]=t;}//换个位置确定这一位数字,然后递归下去
f(k+1);
{int t;t=a[i];a[i]=a[k];a[k]=t;}//回溯,以此来搞定剩下的全排列
}
}
int main(){
f(0);
cout <<ans;
return 0;
}
09 打印图形
如下的程序会在控制台绘制分形图(就是整体与局部自相似的图形)。
当n=1,2,3的时候,输出如下:请仔细分析程序,并填写划线部分缺少的代码。
n=1时:
o
ooo
o
n=2时
o
ooo
o
o o o
ooooooooo
o o o
o
ooo
o
n=3时
o
ooo
o
o o o
ooooooooo
o o o
o
ooo
o
o o o
ooo ooo ooo
o o o
o o o o o o o o o
ooooooooooooooooooooooooooo
o o o o o o o o o
o o o
ooo ooo ooo
o o o
o
ooo
o
o o o
ooooooooo
o o o
o
ooo
o
源代码
c
#include <stdio.h>
#include <stdlib.h>
void show(char* buf, int w){
int i,j;
for(i=0; i<w; i++){
for(j=0; j<w; j++){
printf("%c", buf[i*w+j]==0? ' ' : 'o');
}
printf("\n");
}
}
void draw(char* buf, int w, int x, int y, int size){
if(size==1){
buf[y*w+x] = 1;
return;
}
int n = _________________________ ; //填空
draw(buf, w, x, y, n);
draw(buf, w, x-n, y ,n);
draw(buf, w, x+n, y ,n);
draw(buf, w, x, y-n ,n);
draw(buf, w, x, y+n ,n);
}
int main()
{
int N ;
scanf("%d",&N);
int t = 1;
int i;
for(i=0; i<N; i++) t *= 3;
char* buf = (char*)malloc(t*t);
for(i=0; i<t*t; i++) buf[i] = 0;
draw(buf, t, t/2, t/2, t);
show(buf, t);
free(buf);
return 0;
}
Java
import java.util.Scanner;
public class Main
{
static void show(byte[][] buf){
for(int i=0; i<buf.length; i++){
for(int j=0; j<buf[i].length; j++){
System.out.print(buf[i][j]==0? ' ' : 'o');
}
System.out.println();
}
}
static void draw(byte[][] buf, int x, int y, int size){
if(size==1){
buf[y][x] = 1;
return;
}
int n = ________________________ ; // 填空
draw(buf, x, y, n);
draw(buf, x-n, y ,n);
draw(buf, x+n, y ,n);
draw(buf, x, y-n ,n);
draw(buf, x, y+n ,n);
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int t = 1;
for(int i=0; i<N; i++) t *= 3;
byte[][] buf = new byte[t][t];
draw(buf, t/2, t/2, t);
show(buf);
}
}
#include <stdio.h>
#include <stdlib.h>
void show(char* buf, int w){
int i,j;
for(i=0; i<w; i++){
for(j=0; j<w; j++){
printf("%c", buf[i*w+j]==0? ' ' : 'o');
}
printf("\n");
}
}
void draw(char* buf, int w, int x, int y, int size){
if(size==1){
buf[y*w+x] = 1;
return;
}
int n = size / 3; //填空
draw(buf, w, x, y, n);
draw(buf, w, x-n, y ,n);
draw(buf, w, x+n, y ,n);
draw(buf, w, x, y-n ,n);
draw(buf, w, x, y+n ,n);
}
int main()
{
int N ;
scanf("%d",&N);
int t = 1;
int i;
for(i=0; i<N; i++) t *= 3;
char* buf = (char*)malloc(t*t);
for(i=0; i<t*t; i++) buf[i] = 0;
draw(buf, t, t/2, t/2, t);
show(buf, t);
free(buf);
return 0;
}
10 单峰序列
输入格式
输入一行包含两个整数n,m,中间用一个空格分隔。
输出格式
输出一行包含一个整数表示答案,答案可能很大,请输出答案除以1000000007的余数。
样例输入1
2 3
样例输出1
3
样例说明1
A可能为(3)、(1,2)或(2,1)。
样例输入2
10001 20223
样例输出2
259920306
评测用例规模与约定
对于25的评测用例,n,m≤10;
对于50的评测用例,n,m≤300;
对于75的评测用例,n,m≤5000;
对于所有评测用例,1≤n,m≤100000。
动态规划
请填写解题思路令dp[]们]表示长度为i,总和为j的不同严格递增数组的个数(例如dp[2][3]=1),再对每一个严格递增数组固定最大值,将其他数分配到左右两侧,长度为n的严格递增数组的不同单峰序列组合数为pow(2,n-1);
接下来是dp方程的递推式第一步:dp[i][j]可以由d[i][j-i]上的每一个数都加1得到,但是注意到这样推导得到的dp[i][j]的递增序列集合中是没有元素1的,因为d[i][j-i]的元素都加1后的序列最小值为2.
第二步:基于以上问题,把含有元素1的递增序列作为特殊情况加上去,dp[i][j]中含有1元素的子集个数怎么计算呢?可以先固定一个元素1,因此等于求长度为i-1,总和为j-1,且最小元素不为1的递增序列。注意到最小元素不为1,也就是说最小元素为2,回头看第
一步求出来的序列最小值不就是2吗,因此d[i-1][j-1]=d[i-1][j-1-(i-1)]=dp[i-1][j-1]。
综上所述dp[i][j]=dp[i][j-i]+dp[i-1][j-i] 当j<=i,dp[i][j]=0;
dp数组的边界值只需初始化i=0时的值为0,i=1的值为1即可;
#include <iostream>
#include<cmath>
#include<vector>
using namespace std;
int main()
{
// 请在此输入您的代码
long long c_(int x);
int n, m, p = 1000000007;
cin >> n;
cin >> m;
int N = sqrt(2 * m) + 2;
while (N * (N + 1) > 2 * m)N--;
n = min(n, N);
vector<vector<int>>dp(n + 1, vector<int>(m + 1));
for (int i = 0; i < m + 1; i++)dp[1][i] = 1;
for (int i = 2; i < n + 1; i++) {
for (int j = 1; j < m + 1; j++) {
if (j - i > 0)dp[i][j] = (dp[i][j - i] + dp[i - 1][j - i]) % p;
}
}
/*for (int i = 0; i < n + 1; i++) {
for (int j = 0; j < m + 1; j++)cout << dp[i][j] << " ";
cout << endl;
}*/
int ans = 1;
for (int i = 2; i < n + 1; i++) {
ans = (ans + (long(dp[i][m])*c_(i - 1))%p) % p;
//cout << (long(dp[i][m]) * c_(i - 1)) % p << " ";
}
cout << ans;
return 0;
}
long long c_(int x) {
long long ans = 1;
int p = 1000000007;
for (int i = 0; i < x; i++) {
ans = (ans * 2) % p;
}
//cout << x << " " << ans << endl;
return ans;
}