Living-Dream 系列笔记 第1期
本期主要讲解模拟、枚举算法。
例题
T1
简单模拟题。
利用 scanf/cin 以 int 形式读入分和秒,并令秒循环累加,逢 \(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;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号