模拟:根据题目要求编写代码
可分为:图形排版(根据某种规则输出特定图形)、日期问题、其他模拟
一.图形排版
1.输出梯形(清华大学)
法一:等差数列
分析:每行的星号个数为等差数列2n+2(n=1,2,3,…)
#include<iostream>
using namespace std;
int main() {
int n = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
int j = 0;
for (; j < 2 * n + 2 - (2 * i + 2); j++) {
cout << " ";
}
for (; j < 2 * n + 2; j++) {
cout << "*";
}
cout << endl;
}
}
法二:梯形求解
分析:设第0行有h个星号,第1行有h+2个,第2行有h+2* 2个,第i行有h+2* i个
若该梯形的高为h,则最后一行是第h-1行,星号数为h+2* (h-1)
则第一行的空格数=h+2* (h-1)-h
第i行的空格数=h+2* (h-1)-(h+2* i)=2(h-1-i)个
即第i行的空格数为2(h-1-i)个,星号数为h+2* i个
#include<iostream>
using namespace std;
int main() {
int h=0;
while (scanf("%d",&h) != EOF) {
for (int i = 0; i < h; i++) {
for (int j = 0; j < 2 * (h - 1 - i); j++) {
cout << " ";
}
for (int j = 0; j < h+2*i; j++) {
cout << "*";
}
cout << endl;
}
}
}
2.叠筐(杭州电子科技大学-2074)
评测系统
法一:
#include<iostream>
using namespace std;
int main() {
int n=0;
char b, a;
while (cin >> n) {
cin >> b >> a;
string out[100];
int count = 0;
//特殊处理
if (n == 1) {
cout << b <<endl << endl;
continue;
}
//决定开头字符
if ((n - 1) / 2 % 2 == 0) {
int temp = a;
a = b;
b = temp;
}
//第一行
out[count] += " ";
for (int i = 0; i < n - 2; i++) {
out[count] += a;
}
out[count] += " ";
count++;
//第二行往后
int num = 0;
char arr[100] = { 0 };
for (int i = 0; i < n / 2; i++) {
if (i) {
int temp = a;
a = b;
b = temp;
}
arr[num] = a;
arr[n - num] = a;
for (int j = 0; j <= num; j++) {
out[count] += arr[j];
}
for (int j = num + 1; j < n - num - 1; j++) {
out[count] += b;
}
for (int j = n - num; j <= n; j++) {
out[count] += arr[j];
}
num++;
count++;
}
//输出
for (int i = 0; i < count; i++) {
cout << out[i] << endl;
}
for (int i = count - 2; i >= 0; i--) {
cout << out[i] << endl;
}
cout << endl;
}
}
法二:
先补全四个角,可以看出,这是一个同心正方形,边长为n
以最外层左上角为坐标原点(0,0),向下向右展开坐标轴,右下角坐标为(n-1,n-1),最外层正方形边长为n
对于任意内层正方形,设左上角的坐标为(i,i),右下角的坐标为(j,j),则该正方形边长为n-2i
(i,i)和(j,j)两坐标相加即可得到右下角的坐标(n-1,n-1),因此有等式i+j=n-1成立
i的取值从0到n/2,当i=n/2时为中心花色
设输入的第一个字符是B,第二个字符是A
中心花色是第一个输入字符
向外圈填充,距离中心距离为1填充字符为第二个输入字符
向外圈填充,距离为2填充第一个输入字符
以此类推,左上角坐标(i,i)距离中心的距离=n/2-i
距离为奇数填充第二个输入字符
距离为偶数填充第一个输入字符
char c;//当前圈层填充的字符
if ((n / 2 - i) % 2 == 0) {//偶数
c = 第一个输入字符;
}
else {
c = 第二个输入字符;
}
完整代码
#include<iostream>
using namespace std;
char matrix[80][80];//输出数组
int main() {
int n;
char a, b;
bool firstCase = true;
while (scanf("%d %c %c", &n, &a, &b) != EOF) {
if (firstCase == true) {
firstCase = false;//第一组前面无需换行
}
else { //在运行前先输出换行,确保两组用例之间有换行
printf("\n");
}
for (int i = 0; i <= n / 2; i++) {//(i,i)为某正方形左上角坐标
int j = n - 1 - i;//(j,j)为某正方形右下角坐标
int length = n - 2 * i;//正方形边长
char c;//当前圈层填充的字符
if ((n / 2 - i) % 2 == 0) {//偶数
c = a;
}
else {
c = b;
}
for (int k = 0; k < length; k++) {//为当前圈层赋值
matrix[i][i + k] = c;//上边赋值
matrix[i+k][i] = c;//左边赋值
matrix[j][j-k] = c;//下边赋值
matrix[j-k][j] = c;//右边赋值
}
}
if (n != 1) {//剔除四个角,确保外框尺寸n=1时也有输出,此时输出的是中心花色
matrix[0][0] = ' ';
matrix[0][n - 1] = ' ';
matrix[n - 1][0] = ' ';
matrix[n - 1][n - 1] = ' ';
}
for (int i = 0; i < n; i++) {//输出
for (int j = 0; j < n; j++) {
printf("%c", matrix[i][j]);
}
printf("\n");
}
}
return 0;
}
3.Hello World for U(浙江大学)
评测系统
#include<iostream>
#include<string.h>
using namespace std;
int main() {
string n;
while (cin >> n) {
int len = n.length();
int n1, n2;
int flag = 0;
for (n1 = len - 1; n1 >= 2; n1--) {
for (n2 = len - 1; n2 >= 3; n2--) {
if (2 * n1 + n2 - 2 == len && n1 <= n2) {
flag = 1;
break;
}
}
if (flag == 1) {
break;
}
}
flag = 0;
char a[1000][1000];
int num = 0;
int i, j;
for (i = 0; i < n1; i++) {
a[i][0] = n[num];
num++;
}
i -= 1;
for (j = 1; j < n2; j++) {
a[i][j] = n[num];
num++;
}
j -= 1;
for (int k = i - 1; k >= 0; k--) {
a[k][j] = n[num];
num++;
}
for (i = 0; i < n1 - 1; i++) {
int ko = n2 - 2;
cout << a[i][0];
while (ko--) {
cout << " ";
}
cout << a[i][n2 - 1] << endl;
}
for (j = 0; j < n2; j++) {
cout << a[i][j];
}
cout << endl;
}
}
二.日期问题
【求天数】
1.今年的第几天?(清华大学)
评测系统
#include<iostream>
#include<string.h>
using namespace std;
int count(int m,int y) {
int sum=0;
for (int i = 1; i <= m; i++) {
if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
sum += 31;
}
else if (i == 2) {
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) {
sum += 29;
}
else
sum += 28;
}
else
sum += 30;
}
return sum;
}
int main() {
int year, month, day;
while (cin >> year >> month >> day) {
cout << count(month - 1, year) + day << endl;
}
}
另一种方式
#include<iostream>
#include<string.h>
using namespace std;
int daytab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},//不是闰年
{0,31,29,31,30,31,30,31,31,30,31,30,31},//是闰年
};
bool IsLeapYear(int year) {//是否闰年
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int main() {
int year, month, day;
int number=0;
while (scanf("%d%d%d", &year, &month,&day) != EOF) {
int number = 0;
int row = IsLeapYear(year);
for (int j = 0; j < month; ++j) {
number += daytab[row][j];
}
number += day;
printf("%d\n", number);
}
return 0;
}
【求日期B】
2.打印日期(华中科技大学)
评测系统
#include<iostream>
#include<string.h>
using namespace std;
int a[2];
void count(int y,int x) {
int sum=0;
int premonthday2 = 0;//上个月
int premonthday3 = 0;//上上个月
for (int i = 1; i <= 12; i++) {
if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
sum += 31;
premonthday2 = 31;
}
else if (i == 2) {
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) {
sum += 29;
premonthday2 = 29;
}
else {
sum += 28;
premonthday2 = 28;
}
}
else {
sum += 30;
premonthday2 = 30;
}
if (x < sum) {
if (i != 1) {
a[0] = i;
}
else {
a[0] = 1;
}
a[1] = x+premonthday2-sum;
if (a[1] == 0) {
a[0] -= 1;
a[1] = premonthday3;
}
return;
}
premonthday3 = premonthday2;
}
}
int main() {
int year, month, day;
int daycount;
while (cin >> year>> daycount) {
count(year,daycount);
printf("%04d-%02d-%02d\n", year, a[0], a[1]);
}
}
另一种方式
#include<iostream>
#include<string.h>
using namespace std;
int daytab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},//不是闰年
{0,31,29,31,30,31,30,31,31,30,31,30,31},//是闰年
};
bool IsLeapYear(int year) {//是否闰年
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int main() {
int year, month, day;
int number;
while (scanf("%d%d", &year, &number) != EOF) {
month = 0;
int row = IsLeapYear(year);
while (number > daytab[row][month]) {
number -= daytab[row][month];
month++;
}
day = number;
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
3.日期累加(北京理工大学)
评测系统
#include<iostream>
#include<string.h>
using namespace std;
int daytab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},//不是闰年
{0,31,29,31,30,31,30,31,31,30,31,30,31},//是闰年
};
bool IsLeapYear(int year) {//是否闰年
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int NumberOfYear(int year) {//返回该年天数
if (IsLeapYear(year)) {
return 366;
}
else
return 365;
}
int main() {
int m = 0;
cin >> m;
int year, month, day,number;
while (m--) {
cin >> year >> month >> day >> number;
int row = IsLeapYear(year);
for (int j = 0; j < month; j++) {//加上今年已经过的天数
number += daytab[row][j];
}
number += day;
while (number > NumberOfYear(year)) {//确定年
number -= NumberOfYear(year);
year++;
}
month = 0;
row = IsLeapYear(year);
while (number > daytab[row][month]) {//确定月
number -= daytab[row][month];
month++;
}
day = number;//确定日
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
4.日期差值(上海交通大学)
评测系统
#include<iostream>
#include<string.h>
using namespace std;
int daytab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},//不是闰年
{0,31,29,31,30,31,30,31,31,30,31,30,31},//是闰年
};
bool IsLeapYear(int year) {//是否闰年
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int NumberOfYear(int year) {//返回该年天数
if (IsLeapYear(year)) {
return 366;
}
else
return 365;
}
int main() {
string s1, s2;
while (cin >> s1 >> s2) {
int year1, month1, day1;
int year2, month2, day2;
int sum = 0;
year1 = (s1[0] - 48) * 1000 + (s1[1] - 48) * 100 + (s1[2] - 48) * 10 + s1[3] - 48;
year2 = (s2[0] - 48) * 1000 + (s2[1] - 48) * 100 + (s2[2] - 48) * 10 + s2[3] - 48;
month1 = (s1[4] - 48) * 10 + s1[5] - 48;
month2 = (s2[4] - 48) * 10 + s2[5] - 48;
day1 = (s1[6] - 48) * 10 + s1[7] - 48;
day2 = (s2[6] - 48) * 10 + s2[7] - 48;
//处理中间年份
for (int i = year1 + 1; i < year2; i++) {
sum += NumberOfYear(i);
}
//处理两端年份
if (month1 == month2) {
if (day1 == day2) {
sum += 0;
}
else {
sum += abs(day1 - day2)+1;
}
}
else {
int row = IsLeapYear(year1);
sum += daytab[row][month1] - day1 + 1;
sum += day2;
if (year1 == year2) {//没跨年,月份只会增大
for (int i = month1 + 1; i < month2; i++) {
sum += daytab[row][i];
}
}
else {//跨年,分两段算
for (int i = month1 + 1; i <= 12; i++) {
sum += daytab[row][i];
}
for (int i = 1; i < month2; i++) {
sum += daytab[row][i];
}
}
}
cout << sum << endl;
}
}
5.Day of Week(上海交通大学)
评测系统
分析:
蔡勒公式
1.基本公式
日期≤1582年10月4日↓
日期>1582年10月4日↓
其中:
w是星期,w=0表示星期日,w=1表示星期一…
c是年份的前两位数
y是年份的后两位数
m是月份(一月m=13,二月m=14,三月m=3,四月m=4…十二月m=12)
当m=13或14时,年份要-1,即2003年变为2002年
如2002年2月5日
年份=2001
月份=14
日=5
也可采用 w=(day+2month+3(month+1)/5+year+year/4-year/100+year/400+1)%7
其中y为四位数的年份
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
int main() {
string s;
while (getline(cin,s)) {
int i;
int year, year2, month, day;
int yearnum, monthnum, daynum;
year = month = day = year2= 0;
yearnum = monthnum = daynum = 0;
for (i=0; ; i++) {
if (s[i] == ' ')
break;
day = day * 10 + s[i]-48;
}
daynum = i - 1;
string month2;
for (i += 1; ; i++) {
if (s[i] == ' ')
break;
month2 += s[i];
}
if (month2 == "January") {
month = 1;
}
else if (month2 == "February") {
month = 2;
}
else if (month2 == "March") {
month = 3;
}
else if (month2 == "April") {
month = 4;
}
else if (month2 == "May") {
month = 5;
}
else if (month2 == "June") {
month = 6;
}
else if (month2 == "July") {
month = 7;
}
else if (month2 == "August") {
month = 8;
}
else if (month2 == "September") {
month = 9;
}
else if (month2 == "October") {
month = 10;
}
else if (month2 == "November") {
month = 11;
}
else {
month = 12;
}
i += 1;
year = (s[i]-48) * 10 + (s[i + 1]-48);
year2 = (s[i + 2]-48) * 10 + (s[i + 3]-48);
if (month == 1) {
month = 13;
if (year2 != 0)
year2--;
else
year--;
}
if (month == 2) {
month = 14;
if (year2 != 0)
year2--;
else
year--;
}
int wee;
if((year*100+year2<1582)||(year * 100 + year2==1582&&month<10)|| (year * 100 + year2 == 1582 && month == 10&&day<=4))
wee = year2 + year2 / 4 + year / 4 - 2 * year + 26 * (month + 1) / 10 + day + 2;
else
wee = year2 + year2 / 4 + year / 4 - 2 * year + 26 * (month + 1) / 10 + day - 1;
if (wee < 0) {
wee = (wee % 7 + 7) % 7;
}
else
wee = wee % 7;
if (wee == 0) {
cout << "Sunday" << endl;
}
else if (wee == 1) {
cout << "Monday" << endl;
}
else if (wee == 2) {
cout << "Tuesday" << endl;
}
else if (wee == 3) {
cout << "Wednesday" << endl;
}
else if (wee == 4) {
cout << "Thursday" << endl;
}
else if (wee == 5) {
cout << "Friday" << endl;
}
else {
cout << "Saturday" << endl;
}
}
return 0;
}
6.日期类(北京理工大学)
评测系统
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
int main() {
int a[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int m = 0;
cin >> m;
while (m--) {
int year, month, day;
cin >> year >> month >> day;
if (month == 12 && day == 31) {
year++;
day = 1;
month = 1;
}
else if (day == a[month]) {
month++;
day = 1;
}
else {
day++;
}
printf("%04d-%02d-%02d\n", year, month, day);
}
}
三.其他模拟
1.剩下的树(清华大学)
测评系统
分析:
设置一个数组,在给定区间内就将数值设为1,最后统计1的个数
#include<iostream>
#include<string.h>
using namespace std;
int main() {
int a[10005] = { 0 };
int len=0, group = 0;
cin >> len >> group;
for (int k = 0; k < group; k++) {
int m, n;
cin >> m >> n;
for (int i = m; i <= n; i++) {
a[i] = 1;
}
}
int sum = 0;
for (int k = 0; k < len; k++) {
if (a[k] == 1)
sum++;
}
cout << len + 1 - sum;
}
2.手机键盘(清华大学)
评测系统
分析:
每一个字母需要的按键次数
int keytab[26] = { 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4 };
判断两个字母是否位于同一个按键上
若在同一按键上,两个字母的差值=按键次数的差值
例如B-A=2-1=1
C-A=3-1=2
if (str[i] - str[i - 1] == keytab[str[i] - 'a'] - keytab[str[i - 1] - 'a']) {
time += 2;
}
若不在同一按键上,两个字母的差值≠按键次数的差值
G-F≠1-3
完整代码
#include<iostream>
#include<string.h>
using namespace std;
int keytab[26] = { 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4 };
int main() {
string str;
while (cin >> str) {
int time = 0;
for (int i = 0; i < str.size(); i++) {
time += keytab[str[i] - 'a'];//按键时间
if (i != 0 && str[i] - str[i - 1] == keytab[str[i] - 'a'] - keytab[str[i - 1] - 'a']) {
time += 2;
}
}
cout << time << endl;
}
return 0;
}
3.XXX定律(浙江大学)
评测系统
#include<iostream>
using namespace std;
int main() {
int n = 0;
while (cin>>n) {
if (n == 0)
break;
int num = 0;
while (n != 1) {
if (n % 2 == 0) {
n /= 2;
}
else {
n = (3 * n + 1) / 2;
}
num++;
}
cout << num << endl;
}
return 0;
}
4.Grading(浙江大学)
评测系统
#include<iostream>
using namespace std;
float max(float a, float b, float c) {
if (a > b) {
if (a > c)
return a;
else
return c;
}
else {
if (b > c)
return b;
else
return c;
}
}
int main() {
float P, T, G1, G2, G3, GJ;
cin >> P >> T >> G1 >> G2 >> G3 >> GJ;
if (abs(G2 - G1) <= T) {
printf("%.1f", (G1 + G2) / 2);
}
else {
if ((abs(G3 - G1) <= T && abs(G3 - G2) > T)) {
printf("%.1f", (G3 + G1) / 2);
}
else if (abs(G3 - G1) > T && abs(G3 - G2) <= T) {
printf("%.1f", (G3 + G2) / 2);
}
else if (abs(G3 - G1) <= T && abs(G3 - G2) <= T) {
printf("%.1f", max(G1, G2, G3));
}
else {
printf("%.1f", GJ);
}
}
}