有一个类型的题目是找到输出图形的规律,然后将其实现。观察下面的图形。你想想你该怎么输出这个图形呢?
A
BBB
#include<stdio.h>
int main(){
printf(" A\n");
printf("BBB\n");
return 0;
}
那么,对于如下的图形:
A
BBB
CCCCC
#include<stdio.h>
int main(){
printf(" A\n");
printf(" BBB\n");
printf("CCCCC\n");
return 0;
}
前面分别对应的是输出两层和三层的情况。我们输入需要输出的层数n,当n≤5的时候,我们可以枚举n的不同取值,然后分别输出。如果需要输出更多层,按照上面的方法,确实可以完成任务,但是对应的代码量会更大,编码时间也更长。因此当n>5的时候,我们就需要一些其他的方法来简化代码实现。
仔细观察会发现,第i层输出的前面的空格数(尾部不需要输出空格)和字符的个数都是有规律的,可以根据n和i计算出来。对应输出的字符的ASCI码是‘A’+i-1,其中‘A’可以直接表示字符A的ASCI码。然后我们就可以直接用循环控制来输出了。
给定一个层数n,
输出字母三角形。
输入格式
输入一个整数n(0<n<=26),表示字母三角形
的层数。
输出格式
按照题目播述,输出字母三角形。
样例输入1
2
样例输出1
A
BBB
样例输入2
3
样例输出2
A
BBB
CCCCC
#include<iostream>
#include<string>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
string space = string(n-i,' ');
string ch = string(2*i-1,'A'+i-1);
cout<<space+ch<<endl;
}
return 0;
}
这次我们输出一个稍微复杂的三角形,输入一个大写字母(A-Z)或者一个数字(1-9)。
比如输入是F的时候,编出:
A
ABA
ABCBA
ABCDCBA
ABCDEDCBA
ABCDEFEDCBA
输入是3的时候,输出:
1
121
12321
输入格式
输入一个数字(1-9)或者一个大写字母
#include<iostream>
using namespace std;
int main(){
char c;
cin>>c;
if(c>='A'&&c<='Z'){
for(int i=1;i<=c-'A'+1;i++){
for(int j=1;j<=c-'A'+1-i;j++){
cout<<" ";
}
for(int j=1;j<=i;j++){
cout<<(char)('A'+j-1);
}
for(int j=i-1;j>=1;j--){
cout<<(char)('A'+j-1);
}
cout<<endl;
}
}
else{
for(int i=1;i<=c-'1'+1;i++){
for(int j=1;j<=c-'1'+1-i;j++){
cout<<" ";
}
for(int j=1;j<=i;j++){
cout<<(char)('1'+j-1);
}
for(int j=i-1;j>=1;j--){
cout<<(char)('1'+j-1);
}
cout<<endl;
}
}
return 0;
}
假设地图是一个n行rn列的方格地图,地图等个
格子·代表一个宝题。比如2行2列的地图如下:
**
**
要建的房子如下:
+-+-+
|*|*|
+-+-+
|*|*|
+-+-+
现在告诉你地图的行列数 画出房子的设计图
输入格式
一行两个整数n,m(0<n,m≤50),分别表示地图行数和列数。
输出格式
按照题目中要求的格式输出地图。
样例输入1
2 2
样例输出1
+-+-+
|*|*|
+-+-+
|*|*|
+-+-+
样例输入2
3 4
样例输出2
+-+-+-+-+
|*|*|*|*|
+-+-+-+-+
|*|*|*|*|
+-+-+-+-+
|*|*|*|*|
+-+-+-+-+
#include<iostream>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<"+-";
}
cout<<"+"<<endl;
for(int j=1;j<=m;j++){
cout<<"|*";
}
cout<<"|"<<endl;
}
for(int j=1;j<=m;j++){
cout<<"+-";
}
cout<<"+"<<endl;
return 0;
}
字符串
字符串是编程语言中非常常用的一种数据类型,字符串的处理也是各类算法竞赛中考察较多的一类题型。字符串,简单地说,就是由若干个字符连接在一起的串。
在C/C++语言中规定,末尾以\0结束的字符型数组称为字符串。这里值得强调的是,只有以\0结束的才能算字符串,否则只
能算作字符型数组。这在C/C++中算是一种标准。也只有以\0结束的字符数组才能以“%s”的方式用printf输出,否则输出的结果会非常奇怪。自己在char数组上构造一个字符串的时候,忘记在末尾加\0可能会导致访问非法内存的错误。
字符串处理函数
很多情况下,都需要对字符串进行复制、剪切、比较等等操作。这些操作理论上都可以自己写代码实现,但是由于这些操作经常使用,每次都要实现一遍太繁琐,现在的大部分语言都提供了基础了字符串操作的库函数。C/C++的字符串处理相关的函数在string.h头文件中。
字符串复制
C/C++中函数原型charstrcpy(chardestin,char*source),将source字符串复制到destin。
C/C++语言示例程序:
#include<stdio.h>
#include<string.h>
int main(){
char name[10];
char *str="adadad";
strcpy(name,str);
printf("%s\n",name);
return 0;
}
字符串拼接
C/C++中函数charstrcat(chardest,char*source),可以将source字符串拼接到dest后面。注意,dest必须有足够的空间来容纳拼接出的字符串。
C/C++示例程序:
#include<stdio.h>
#include<string.h>
int main(){
char dest[25];
char *str1 ="hello", *str2=" ",*str3 ="jisuanke";
strcat(dest,str1);
strcat(dest,str2);
strcat(dest,str3);
printf("%s\n",dest);
return 0;
}
c++字符串可以直接用+号连接
#include<iostream>
using namespace std;
#include<string.h>
int main(){
char dest[25];
string s1="a";
string s2="b";
cout<<s1+s2<<endl;
return 0;
}
字符串比较
C/C++中函数int strcmp(charstr1,charstr2),从第一个字符开始逐字符比较两个字符串的ASCll码。如果下标为i的字符不相等,则函数返回str1[i]-str2[i]。如果两个字符串完全相同,则会返回0。
#include<string.h>
#include<stdio.h>
int main(){
char *str1="cd",*str2="abc";
int res = strcmp(str1,str2);
if(res>0){
printf("%s is greater than %s\n",str1,str2);
}else if(res==0){
printf("%s is same as %s\n",str1,str2);
}else{
printf("%s is less than %s\n", str1,str2);
}
return 0;
}
对称字符串
A1: A
A2:ABA
A3: ABACABA
A4: ABACABADABACABA
. . .
对于给定的N,你能根据规律输出AN吗?
输入格式
仅有一个数:N(N≤20)。
输出格式
一行字符串,表示字符串AN。
样例输入
2
样例输出
ABA
#include<stdio.h>
#include<string.h>
char res[5000000];
int main(){
int n;
scanf("%d",&n);
int len = 0;
for(int i=1;i<=n;i++){
strcat(res+len+1,res);
res[len]='A'+i-1;
len = strlen(res);
}
printf("%s\n",res);
return 0;
}
寻找字符串
在一个字符串里找另一个字符串出现了多少次
找到的结果可以重叠
如一号字符串为abababa, 二号字符串为aba
二号字符串在一号字符串中出现了三次
输入格式
输入包含两行,第一行为一号字符串,第二行为二号字符串
两个字符串肯能包含除换行、回车、\0外的任何字符,两个字符串的长度均不大于1000
样例输入1
i miss you!
you
样例输出1
1
#include<cstdio>
#include<cstring>
char s1[1005],s2[1005];
int main(){
fgets(s1, 1004, stdin);//fgets会读入换行符
fgets(s2,1004,stdin);//用gets就不用-1
int len1 = strlen(s1)-1,len2=strlen(s2)-1;
int ans=0;
for(int i=0;i+len2-1<len1;i++){
bool matched = true;
for(int j=0;j<len2;j++){
if(s1[i + j] != s2[j]){
matched=false;
break;
}
}
if(matched){
ans++;
}
}
printf("%d",ans);
return 0;
}
gets 函数,它的任务是从 stdin 流中读取字符串,直至接收到换行符或 EOF 时停止,并将读取的结果存放在 buffer 指针所指向的字符数组中。这里需要注意的是,换行符不作为读取串的内容,读取的换行符被转换为 null(’\0’) 值,并由此来结束字符串。即换行符会被丢弃,然后在末尾添加 null(’\0’) 字符。
注意:gets函数由于没有指定输入字符大小,所以会无限读取,一旦输入的字符大于数组长度,就会发生内存越界,从而造成程序崩溃或其他数据的错误。
相对于 gets 函数,fgets 函数最大的改进就是能够读取指定大小的数据,从而避免 gets 函数从 stdin 接收字符串而不检查它所复制的缓冲区空间大小导致的缓存溢出问题。
fgets(str, N, stdin) ; str 是指字符数组,N指
最大读入字符数,stdin 表明读取的哪个文件,如果是从键盘上读入数据,可以使用 stdin 作为该参数。
fgets只能读取N-1个字符,包括最后的换行符(’\n’),读完结束后系统将自动在最后加’\0’(gets读完结束后系统自动会将’\n’置换成’\0’)。
当你从键盘上输入 <=N-1 个字符(包括’\n’)时,那么字符串str会以 ‘\n\0’ 结尾。这就造成了strlen(str)比你想象的大 1
当你从键盘上输入>N-1个字符(包括’\n’)时,那么字符串str会以’\0’结尾。
算出生日在星期几
输入格式
输入三个正整数,分别表示年、月、日。保证输入
年份合法。
输出格式
输出星期几。
用Monday、Tuesday、Wednesday、Thursday、Friday、Saturday、Monday表示星期几
样例输入1
1 1 1
样例输出1
Monday
样例输入2
2016 11 29
样例输出2
Tuesday
#include<iostream>
#include<string>
using namespace std;
int whatday(int y,int m,int d){
//返回正确的日期,用0~6表示 星期 1 - 7
int ans = 0;
for(int i=1;i<y;i++){
if((i % 100 !=0&&i%4==0)||i%400==0){
ans+=366%7;
ans%=7;
}else{
ans+=365%7;
ans%=7;
}
}
for(int i=1;i<m;i++){
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12){
ans+=31%7;
ans%=7;
}else if(i==4||i==6||i==9||i==11){
ans+=30%7;
ans%=7;
}else if((y%100!=0&&y%4==0)||y%400==0){
ans+=29%7;
ans%=7;
}
else{
ans+=28%7;
ans%=7;
}
}
ans+=(d-1)%7;
ans%=7;
return ans;
}
string weekday[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
int main(){
int y,m,d;
cin>>y>>m>>d;
cout<<weekday[whatday(y,m,d)]<<endl;
return 0;
}
也可以直接用公式
#include<iostream>
#include<string>
using namespace std;
int whatday(int y,int m,int d){
if(m<=2){
m+=12;
y--;
}
//返回正确的日期,用0~6表示 星期 1 - 7
return(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
}
string weekday[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
int main(){
int y,m,d;
cin>>y>>m>>d;
cout<<weekday[whatday(y,m,d)]<<endl;
return 0;
}
恋爱纪念日
一对情侣想知道他们第100天、200天 . . .纪念日
输入格式
输入4个整数y,m,d,,k,表示他们在一起的日期,保证是一个1900年1月1日以后的日期,求他们的k(0<=k<=10000)天纪念日。
输出格式
输出格式按照yyy-m-dd的格式输出k天纪念日的日期。月份和天数必须各输出2位。保证最后答案年份不超过4位。
样例输入1
2016 10 1 100
样例输出1
2017-01-09
样例输入2
2017 1 1 10
样例输出2
2017-01-11
#include<stdio.h>
int main(){
int y,m,d,k;
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
scanf("%d %d %d %d",&y,&m,&d,&k);
for(int i=1;i<=k;i++){
if((y%4==0)&&y%100!=0||y%400==0){
day[2]=29;
}else{
day[2]=28;
}
d++;
if(d==day[m]+1){
d=1;
m++;
}
if(m==13){
m=1;
y++;
}
}
printf("%04d-%02d-%02d",y,m,d);
return 0;
}
节假日
日历有阳历(公历)和明历(农历)之分。每
都有法定节假日,这些分成三类——双休、阳历假日、阴历节假日。
1.双休
1)周六和周日2天
2.阳历节假日
1)元且:阳历每年1月1日,放假1天
2)劳动节:阳历每年5月1日,放假1天
3)国庆节:阳历每年10月1日,放假3天
4)圣诞节:阳历每年12月25日,放假1天
3.阴历节假日
1)春节:阴历每年1月1日,放假3天
2)清明节:阳历每年4月4-6日之间的某天,放假1天
3)端午节:阴历每年5月5日,放假1天
4)中秋节:阴历每年8月15日,放假1天
当节假日和双体重合时,双休不延后也不提前,保证节假日之间不会重合。现在给你属年的所有明历节假日的阳历日期,以及当年的1月1日是星期几,请你计算出这一年(阳历1月日到12月31日)放了多少天假(包括双休、阳历节假日和明历节假日)。
输入格式
第一行输入年份(1900<y≤2050)。
接下来4行,每行输入两个整数m、d.依次表示春节、清明节、端午节和中秋节的阳历日期。最后一行一个整数表示当年1月1号是星期几(一周内的第几天,每周从星期一开始计数,即星期一为第一天)。
输出格式
输出一个整数,表示当年放假的天数。
样例输入1
2017
1 28
4 4
5 30
10 4
7
样例输出
113
#include<stdio.h>
int mm[10]={1,5,10,10,10,12};
int dd[10]={1,1,1,2,3,25};
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
void nextday(int &y,int &m,int &d){
d++;
if(d==day[m]+1){
d=1;
m++;
}
}
int main(){
int y,w,m,d,sf,ans;
scanf("%d",&y);
for(int i=6;i<=9;i++){
scanf("%d%d",&mm[i],&dd[i]);
}
scanf("%d",&w);
if((y%100!=0&&y%4==0)||y%400==0){
day[2]++;
}
m=1;
d=1;
sf=0;
ans=0;
while(m<13){
if(m==mm[6]&&d==dd[6]){
ans++;
sf=2;
}else if(sf){
ans++;
sf--;
}else if(w==6||w==7){
ans++;
}else{
for(int i=0;i<10;i++){
if(m==mm[i]&&d==dd[i]){
ans++;
break;
}
}
}
nextday(y,m,d);
w++;
if(w==8){
w=1;
}
}
printf("%d\n",ans);
return 0;
}