机试学习笔记03 --排版问题与日期问题

1 排版类问题

1.1 字符菱形+变体

  1. 右下直角三角:先空格,再字符。
#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= n - i; ++j){
			printf(" ");
		}
		for(int j = 1; j <= i; ++j){
			printf("*");
		}
		printf("\n");
	}
	return 0;
} 
  1. 左下直角三角:每行字符和空格的数目和右下三角一样,但是先字符,再空格。
#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){//每行*数目不变,但是要先输出 
		for(int j = 1; j <= i; ++j){
			printf("*");
		}
		for(int j = 1; j <= n - i; ++j){
			printf(" ");
		}
		printf("\n");
	}
	return 0;
} 
  1. 等腰三角:每行总数(2n-1),每行字符数目(2i-1),则总数减字符数目再除2就是空格数目(n-i)。先输出空格,再字符,最后的空格可以不用输出。
#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= n-i; ++j){
			printf(" ");
		}
		for(int j = 1; j <= 2 * i - 1; ++j){
			printf("*");
		}
		printf("\n");
	} 
	return 0;
} 
  1. 倒转等腰三角:很简单,直接从最后一排往前面输出。
  2. 梯形:和三角形一样,简单。
  3. 平行四边形:注意每行总数。
  4. 棱形:两个等腰三角合并。
#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= n-i; ++j){
			printf(" ");
		}
		for(int j = 1; j <= 2 * i - 1; ++j){
			printf("*");
		}
		printf("\n");
	}
	for(int i = n - 1; i >= 1; --i){ //很简单,直接从最后一排往前面输出 
		for(int j = 1; j <= n-i; ++j){
			printf(" ");
		}
		for(int j = 1; j <= 2 * i - 1; ++j){
			printf("*");
		}
		printf("\n");
	} 
	return 0;
} 

1.2 旋转矩阵+变体

  1. 矩阵顺时针旋转90°:(i,j)->(j,m - i + 1)。
#include<bits/stdc++.h>
using namespace std;

int a[105][105];
int b[105][105];

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= m; ++j){
			scanf("%d", &a[i][j]);
		}
	}
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= m; ++j){
			b[j][m - i + 1] = a[i][j];
		}
	}
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= m; ++j){
			printf("%d ", b[i][j]);
		}
		printf("\n"); 
	}
	
	return 0;
} 
  1. 矩阵顺时针旋转180°:要么转两次90°;要么采用坐标变换:(i,j)->(n - i + 1,m - j +1)。
  2. 其它角度类似。
  3. 翻转型:上下翻转,左右翻转,主对角线翻转,副对角线翻转,都类似。
  4. 矩阵螺旋往内旋转:搜索法,规律法。
#include<bits/stdc++.h>
using namespace std;

int a[25][25] = {0};
int main(){
	int n; //每圈的边长 
	scanf("%d", &n);
	int i = 1, j = 1; //行列索引
	//每圈分四步,每步走q-1个格子
	//每圈的起点行列是上一圈+1,终止行列是上一行-1  	
	int add = 1;
	if(n == 1) printf("%d", 1);
	else{
		for(int q = n; q >= 2; q = q-2){
			for(int p = 1; p <= 4*q-4; ++p){
				a[i][j] = add;
				//printf("%d %d %d\n", i, j, a[i][j]);
				if(p <= q-1) i++;
				else if(p > q-1 && p <= 2*q-2) j++;
				else if(p > 2*q-2 && p <= 3*q-3) i--;
				else if(p > 3*q-3 && p < 4*q-4) j--;
				else if(p == 4*q-4) i++;
				add++;
			}
			if(q-2 == 1){
				a[i][j] = add;
			}
		}
		for(int x = 1; x <= n; ++x){ //输出格式左对齐 
			for(int y = 1; y <= n; ++y){
				if(a[x][y] < 10) printf("%d   ",a[x][y]);
				else if(a[x][y] >= 10 && a[x][y] < 100) printf("%d  ",a[x][y]);
				else printf("%d ", a[x][y]);
			}
			printf("\n");
		}
	}
	return 0;
} 
  1. 杨辉三角:按照要求做就行,注意先把数组清0并且从(1,1)开始,给旁边留0计算。
#include<bits/stdc++.h>
using namespace std;

int a[25][25] = {0};

int main()
{
	int n;
	while(scanf("%d", &n) != EOF){
		if(n == 0){ //注意特殊情况 
			break;
		}
		a[1][1] = 1;
		for(int i = 2; i <= n; ++i){
			for(int j = 1; j <= i; ++j){
				a[i][j] = a[i-1][j-1] + a[i-1][j];
			}
		}
		for(int i = 1; i <= n; ++i){
			for(int j = 1; j <= i; ++j){
				printf("%d ",a[i][j]);
			}
			printf("\n");
	}
	}
	return 0;
} 
  1. 2048问题:两步走,先计算和,再移到最靠近非0值的位置。感觉题目有歧义。

2 日期类问题

  1. 闰年判断:(%4 && !%100)||(%400)
  2. 某年某月某日是星期几(即某日期到某日期中间有多少天):先算多少天,注意判断闰年和闰月,然后再用天数模7,加上最初的星期几,推出结果。
#include<bits/stdc++.h>
using namespace std;

struct node{
	int year;
	int month;
	int day;
}p;

int f[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

char *weekday[10] = {"Eight", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

bool isleap(struct node p){
	if((p.year % 4 == 0 && p.year % 100 != 0) || p.year % 400 == 0){
		return 1;
	}
	else{
		return 0;
	}
}

int main()
{
	p.year = 2012;
	scanf("%d%d", &p.month, &p.day);
	if(isleap(p)){
		f[2] = 29;
	}
	else f[2] = 28;
	int sum = 0; //记录相隔的天数 
	for(int i = 4; i <= p.month; ++i){
		if(i != p.month && i == 4){
			sum = sum + f[i] - 12;
		} 
		if(i == p.month && i != 4){
			sum = sum + p.day;
		}
		if(i == p.month && i == 4)
		{
			sum = sum + p.day - 12;
		}
		if(i != p.month && i != 4){
			sum = sum + f[i];
		}
	}
	//printf("%d", sum);
	int add = 4 + sum % 7;
	if(add > 7) add = add % 7;
	printf("%s", weekday[add]);
	return 0;
 } 
  1. 某日期x天后的日期:
#include<bits/stdc++.h>
using namespace std;

struct node{
	int year;
	int month;
	int day;
}p;

int f[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool isleap(struct node p){
	if((p.year % 4 == 0 && p.year % 100 != 0) || p.year % 400 == 0){
		return 1;
	}
	else{
		return 0;
	}
}
int main()
{
	int n;
	while(scanf("%d%d", &p.year, &n) != EOF){
		if(isleap(p)){
			f[2] = 29;
		}
		else f[2] = 28; //必须改回来
		int d = 0;
		for(int i = 1; i <= 12; ++i){
			d = n;
			n = n - f[i];
			if(n <= 0){
				p.month = i; 
				p.day = d;
				break;
			}
		} 
		printf("%d-%02d-%02d\n", p.year, p.month, p.day);
	}
	return 0;
 } 
  1. 某时某分之后x分钟是几时几分:(某点到某点之间有多少分或多少秒)
#include<bits/stdc++.h>
using namespace std;

struct node{
	int hour;
	int minite;
}p;

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		scanf("%d:%d", &p.hour, &p.minite);
		int msum = p.minite + 15;
		int hadd = 0;
		p.minite = msum;
		if(msum >= 60){
			p.minite = msum - 60;
			hadd++;
		}
		int hsum = p.hour + 13 + hadd;
		p.hour = hsum;
		if(hsum >= 24){
			p.hour = hsum - 24;
		}
		printf("%d:%d\n", p.hour, p.minite);
	}
	return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值