Living-Dream 系列笔记 第1期

Posted on 2024-03-09 12:49  _XOFqwq  阅读(5)  评论(0编辑  收藏  举报

本期主要讲解模拟、枚举算法。

例题

T1

简单模拟题。

利用 scanf/cinint 形式读入分和秒,并令秒循环累加,逢 \(60\)\(0\) 并向分进 \(1\),分则是逢 \(24\)\(0\)

在循环的过程中若分秒合起来是回文数字,则退出循环,按照题目格式输出当前时间。

注意开始时间不算。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int h,m; char c;
    cin>>h>>c>>m;
    while(1){
        m++;
        if(m==60) m=0,h++;
        if(h==24) h=0;
        
        if(h/10==m%10&&h%10==m/10) break;
    }
    if(h<10) cout<<0; cout<<h<<':';
    if(m<10) cout<<0; cout<<m;
}

T2

将这个八位数按字符串读入,然后分离出年、月、日。

接着按照上一题的方法,将日期不断累加,这里可以打一个表记录每月天数,当日期大于此月天数就归 \(0\) 并向月份进 \(1\),需要特判二月;月份是逢 \(12\)\(0\) 并向年份进 \(1\),年份则不用进位。

在循环过程中,若当前年月日为回文数,则输出当前年月日,此时不可 break;若当前年份 \(1,2\) 位和 \(3,4\) 位相同,且 \(1\)\(2\) 位不同(即当前年月日为 ABABBABA 形式),则输出当前年月日并退出循环。输出时仍按上一题的格式来。

#include<bits/stdc++.h>
using namespace std;

int y,m,d;
int cnt;
int day[]={-1,31,-1,31,30,31,30,31,31,30,31,30,31};
string s;

int main(){
	cin>>s;
	y=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0');
	m=(s[4]-'0')*10+(s[5]-'0');
	d=(s[6]-'0')*10+(s[7]-'0');
	
	while(1){
		d++;
		if(m==2){
			if(y%4==0&&y%100!=0||y%400==0) day[2]=29;
			else day[2]=28;
		}
		if(d>day[m]) m++,d=0;
		if(m>12) m=0,y++;
		
		if(y/1000==d%10&&y/100%10==d/10&&y/10%10==m%10&&y%10==m/10){
			if(cnt==0){
				cout<<y;
				if(m<10) cout<<0; cout<<m;
				if(d<10) cout<<0; cout<<d;
				cout<<'\n';
				cnt++;
			}
			
			if(cnt==1){
				int a=y/100,b=y%100;
				if(a==b&&a/10!=a%10){
					cout<<y;
					if(m<10) cout<<0; cout<<m;
					if(d<10) cout<<0; cout<<d;
					cout<<'\n';
					break;
				}
			}
		}
	}
	return 0;
}

另:我们老师的思路是按 int 整型读入 \(n\),并不断累加 \(n\),若它是合法日期且是回文数 / ABABBABA 形式,则输出。

T3

典题。

\(date_1\) 循环至 \(date_2\),依次检查是否为合法日期且为回文日期,若是则输出。

#include<bits/stdc++.h>
using namespace std;

int d1,d2,ans;
int day[]={-1,31,-1,31,30,31,30,31,31,30,31,30,31};

bool isdate(int x){
	int m=x/100%100,d=x%100;
	if(m==2){
		int y=x/10000;
		if(y%4==0&&y%100!=0||y%400==0) day[m]=29;
		else day[m]=28;
	}
	return m>=1&&m<=12&&d>=1&&d<=day[m];
}
bool check(int x){
	int y=0,tmp=x;
	while(tmp){
		y=y*10+tmp%10;
		tmp/=10;
	}
	return x==y;
}

int main(){
	cin>>d1>>d2;
	for(int i=d1;i<=d2;i++)
		if(isdate(i)&&check(i)) ans++;
	cout<<ans;
	return 0;
}

T4

虽然上课没讲,但还是说一下。

其实只需要写一个进制转换函数,对 \([1,300]\) 的数依次进行转换,并判断它们是否为回文数即可。

#include<bits/stdc++.h>
using namespace std;

int b;

bool check(string s){
	string x; int l=s.length();
	for(int i=l-1;i>=0;i--) x+=s[i];
	for(int i=0;i<l;i++)
		if(s[i]!=x[i]) return false;
	return true;
}
string trans(int x){
	string s="",ss="";
	while(x){
		if(x%b>9) s+=(char)(x%b-10+'A');
		else s+=(char)(x%b+'0');
		x/=b;
	}
	int l=s.length();
	for(int i=l-1;i>=0;i--) ss+=s[i];
	return ss;
}

int main(){
	cin>>b;
	for(int i=1;i<=300;i++)
		if(check(trans(i*i))) cout<<trans(i)<<' '<<trans(i*i)<<'\n';
	return 0;
}

习题

T5

首先筛出 \(2 \sim n\) 中的所有质数,因为 \(n\) 范围很小,所以连试除法都可以过。我使用的是埃氏筛,老师说可以从 \(i \times i\) 开始标记。

接着 \(O(n^2)\) 地枚举一对质数 \(p_i\)\(p_j\),若 \(p_i = p_j + p_{j - 1} + 1\),则令计数器 \(cnt \gets cnt + 1\)。需要注意,若你和我的判断式子一样,则 \(j\) 需要从 \(2\) 开始。

最后,若 \(cnt \ge k\),则输出 YES,反之输出 NO

#include<bits/stdc++.h>
using namespace std;

int n,k,tot,ans;
bool f[1031];
int p[1031];

void Esh(){
	for(int i=2;i<=n;i++){
		if(!f[i]){
			p[++tot]=i;
			for(int j=i*i;j<=n;j+=i) f[j]=true;
		}
	}
}

int main(){
	cin>>n>>k;
	Esh();
	for(int i=1;i<=tot;i++)
		for(int j=2;j<i;j++)
			if(p[i]==p[j]+p[j-1]+1)
				ans++;
	cout<<(ans>=k?"YES":"NO");
	return 0;
}

T6

字符串题。

读入四行字符串,统计每个字母出现的次数,存入 \(ch\) 数组,记次数最多的字母出现的次数为 \(x\)

\(x\) 循环至 \(1\),遍历 \(ch\) 数组,若当前字母的出现次数 \(\ge\) 行数,则输出 * \(+\) 一个空格,是最后一行则输出 *;若当前字母出现 \(0\) 次,则输出两个空格,是最后一行则输出一个空格。

在最后一行下方需要输出 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

#include<bits/stdc++.h>
using namespace std;

string t;
int ch[31],x;

int main(){
    getline(cin,t); for(int i=0;t[i];i++) if(isupper(t[i])) ch[t[i]-'A'+1]++;
    getline(cin,t); for(int i=0;t[i];i++) if(isupper(t[i])) ch[t[i]-'A'+1]++;
    getline(cin,t); for(int i=0;t[i];i++) if(isupper(t[i])) ch[t[i]-'A'+1]++;
    getline(cin,t); for(int i=0;t[i];i++) if(isupper(t[i])) ch[t[i]-'A'+1]++;
    for(int i=1;i<=26;i++) x=max(x,ch[i]); 

    
    for(int i=x;i>=1;i--){
        for(int j=1;j<=26;j++){
            if(ch[j]>=i){
                if(j<26) cout<<"* ";
                else cout<<"*";
            }
            else{
                if(j<26) cout<<"  ";
                else cout<<" ";
            }
        }
        cout<<"\n";
    }
    cout<<"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    return 0;
}