简单模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
# 输入要用double
double n;
scanf("%lf",&n);
# 输出要有换行符,注意输出格式,可以使用%g
if(n>5000) printf("discount=0.8,pay=%.1f\n",n*0.8);
else if(n>3000) printf("discount=0.85,pay=%.1f\n",n*0.85);
else if(n>2000) printf("discount=0.9,pay=%.1f\n",n*0.9);
else if(n>1000) printf("discount=0.95,pay=%.1f\n",n*0.95);
else printf("discount=1,pay=%.1f\n",n);
return 0;
}

1722

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <string> // 必须包含string头文件
#include <cctype> // 用于toupper函数(转大写)

using namespace std;


int main()
{
// 权重单开一条,而不是string s[19];
int weights[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
// 记录映射要使用string
string num_map_str[11] = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
// 获取输入
string id_card;
while(cin >> id_card){
int sum=0;
// 测试用例中只给了判断长度是否合理,但我们也要自行判断出数字中是否含有不合法字符
bool is_valid = true;
// 先判断长度,但并没有辨别纯数字的方法,故要在循环中判断
if(id_card.length()!=18){
cout<<"ID Wrong"<<endl;
is_valid=false;
// 因为是多组输入所以用continue
continue;
}
for(int i=0;i<17;i++){
if(!isdigit(id_card[i])){
is_valid=false;
break;
}
// 字符型数字想变成数字型要减去字符0
sum += (id_card[i]-'0')*weights[i];
}
// string好用多用所以这里不用char。而且输入进来的id_card是字符expect_num也是字符。
// 全程只有一个权重是数字,就连计算中也是把输入减去字符0
string expect_num=num_map_str[sum%11];
if(expect_num[0]!=id_card[17]){
is_valid=false;
}
if(is_valid) printf("ID Corrent\n");
else printf("ID Wrong\n");
}
}

进制转换

10转2

十进制为输入,则输入的是数字,转成字符数组,输出也是字符数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <string.h>
#include <cctype>

using namespace std;


int main()
{
int n,k=0;
char a[105]={0};
while(scanf("%d",&n)!=EOF){
//要有输入为零的临界值判断
if(n==0) continue;
//多组输入一定要放在中间,且数组要初始化为零
int k=0;
char a[105]={0};
for(int i=0;n>0;i++){
a[i]=n%2+'0';
n/=2;
k++;
}
//逆序输出注意初始值和等号
for(int i=k-1;i>=0;i--){
printf("%c",a[i]);
}
printf("\n");
}
}

10进制转x

十进制为输入,则输入的是数字,转成字符数组,输出也是字符数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>
#include <cctype>

using namespace std;


int main()
{
// n-待转换的十进制数,x-目标进制(如2表示二进制、16表示十六进制)
int n,x;
char ss[105];
scanf("%d %d",&n,&x);
int i=0;
// 除基取余法:反复除以目标进制,取余数得到进制位
while(n>0){
int num=(n%x);
// 余数<10:直接转换为数字字符(如5 + '0' = '5')
if(num<10) ss[i++]=num+'0';
// 余数≥10:转换为大写字母(如10→'A'、11→'B'...,需先减10再加'A'的ASCII值)
else ss[i++]=num-10+'A';
// 去掉已处理的最低位,继续处理商的部分
n/=x;
}
// 因为余数是从低位到高位存储的,所以需要倒序输出才是正确结果
for(int j=i-1;j>=0;j--){
printf("%c",ss[j]);
}
printf("\n");
}

2转10

二进制为输入,输入为字符串。如果是零,数值翻倍。如果是一,翻倍后再加一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string.h>
#include <cctype>

using namespace std;


int main()
{
// 输入要是一个字符串
char s[105];
cin>>s;
int ans=0;
// 获取长度是strlen(),而且前面要加上头文件#include <string.h>
for(int i=0;i<strlen(s);i++){
if(s[i]=='0')
ans*=2;
else
ans=ans*2+1;
}
printf("%d",ans);
}

x转10

先自乘进制(相当于把x进制的每一位乘上进制),再加上这一位的字符值减去‘0’或者‘A’或者‘a’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string.h>
#include <cctype>

using namespace std;


int main()
{
int x;
// 输入要是一个字符串
char s[105];
cin>>s>>x;
int ans=0;
// 获取长度是strlen(),而且前面要加上头文件#include <string.h>
for(int i=0;i<strlen(s);i++){
ans*=x;
if(s[i]>='0'&&s[i]<='9')
ans+=s[i]-'0';
else
ans+=s[i]-'A'+10;
}
printf("%d",ans);
}

x转y

x先转10,10再转y

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <string.h>
#include <cctype>

using namespace std;


int main()
{
// m进制转成十进制
// 坑点在数据范围要用longlong
long long m,n;
char x[105]={0};
cin>>m>>n>>x;
long long ans=0;
for(int i=0;i<strlen(x);i++){
ans*=m;
if(x[i]>='0'&&x[i]<='9') ans+=x[i]-'0';
//m转10是减A加十
else ans+=x[i]-'A'+10;
}
// 十进制转成n进制

char x2[105]={0};
long long k=0;
if(ans==0) x2[k++]='0';
else{
while(ans>0){
int ans2=ans%n;
// 数字转字符判断为0和9而不是'0'和'9'
if(ans2>=0&&ans2<=9) x2[k++]=ans2+'0';
// 10转n是减十加A
else x2[k++]=ans2-10+'a';
ans/=n;
}
}

for(int j=k-1;j>=0;j--){
printf("%c",x2[j]);
}
}

1176

大数字直接使用python

format()format(value, format_spec)的工作原理可以拆解为:

  • 第一个参数value:要格式化的对象(这里必须是整数,因为'b'只适用于整数);
  • 第二个参数format_spec:格式指令(不同的字符对应不同的进制 / 格式)。

int(x, base)的底层规则:

  1. base参数可以指定2~36之间的任意整数(对应二进制到三十六进制);

  2. 函数会把x看作base进制的数值,然后转换为十进制整数;

  3. 如果省略base,默认是10(十进制)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    while True:
    try:
    a=int(input())
    b=format(a,'b')
    b1=b[::-1]
    b2=int(b1,2)
    print(b2)
    except:
    break

排版问题

输出菱形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string.h>
#include <cctype>

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<=1+2*(i-1);j++){
printf("*");
}
printf("\n");
}
//打印下半部分,对于下半部分关键在于i是反过来的
for(int i=n-1;i>=1;i--){
//打印空格
for(int j=1;j<=n-i;j++){
printf(" ");
}
//打印下半部分
for(int j=1;j<=1+2*(i-1);j++){
printf("*");
}
printf("\n");
}
}

杨辉三角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string.h>
#include <cctype>

using namespace std;

//编排类代码好像都是ij从一开始,因为这样可以避免如杨辉三角这样需要读取边缘得令的情况
int main()
{
int n;
// 一直读取输入
while(scanf("%d",&n)!=EOF){
// 判零逻辑在这里
if(n==0) break;
int arr[21][21]={0};
arr[1][1]=1;
// 从第二行开始计算数字
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
}

1377旋转方阵

思路是写一个旋转90°的函数

关键在于旋转时,交换数组需要使用一个新的,避免原数组被覆盖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# include <bits/stdc++.h>
using namespace std;

//变量要是全局变量
int n,a;
int arr1[10][10]={0},arr2[10][10]={0};
//增加一个临时数组用来存储旋转后的结果,避免覆盖原数组
int temp1[10][10] = {0},temp2[10][10] = {0},temp3[10][10] = {0};

bool isEqual(int arr1[10][10],int arr2[10][10])
{
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(arr1[i][j]!=arr2[i][j]){
return false;
}
}
}
return true;
}

void rotate90(int mat[10][10], int res[10][10]) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// m行,n列
// 下标从1开始的90°旋转公式:原(i,j) → 新(j, n-i+1)
res[j][n - i + 1] = mat[i][j];
// 逆时针旋转:(i,j)->(n-j+1, i),沿纵向对称轴翻折:(i, j)->(i, m-j+1)
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF){
// 多组输入一定要初始化
int arr1[10][10]={0},arr2[10][10]={0};
int temp1[10][10] = {0},temp2[10][10] = {0},temp3[10][10] = {0},temp4[10][10] = {0};
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a);
arr1[i][j]=a;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%d",&a);
arr2[i][j]=a;
}
}
if (isEqual(arr1, arr2)) {
printf("0\n");
continue;
}
// 第一次旋转90°,检查90°
// 这里要使用两个数组作为旋转函数的输入,因为只有一个数组的话会原地覆盖,此时的temp为空数组,可以用来存放旋转后的矩阵
rotate90(arr1, temp1);
if (isEqual(temp1, arr2)) {
printf("%d\n", 90);
continue;
}

// 第二次旋转90°(累计180°),检查180°
rotate90(temp1, temp2); // 用temp覆盖自身,节省空间
if (isEqual(temp2, arr2)) {
printf("%d\n", 180);
continue;
}

// 第三次旋转90°(累计270°),检查270°
rotate90(temp2, temp3);
if (isEqual(temp3, arr2)) {
printf("%d\n", 270);
continue;
}

// 都不匹配,输出-1
printf("%d\n", -1);
}
return 0; // main正常退出返回0
}

1216

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# include <bits/stdc++.h>
using namespace std;

int main()
{
int n;
cin>>n;
// 开头不用初始化
int a[30][30];
// 矩阵中n*n的部分要初始化为-1
for(int i=0;i<30;i++){
for(int j=0;j<30;j++){
a[i][j]=-1;
}
}
int flag=1;
int num=1,i=0,j=0;
while(num<=n*n)
{
if(a[i][j]==-1){
a[i][j]=num;
num++;
}
if(flag==1){
i++;
// 这里是大于等于而非等于,因为i的边界在n-1
if(i>=n||a[i][j]!=-1){
i--;
flag=2;
}
}
else if(flag==2){
j++;
if(j>=n||a[i][j]!=-1){
j--;
flag=3;
}
}
else if(flag==3){
i--;
// i等于0时也不越界,必须小于零
if(i<0||a[i][j]!=-1){
i++;
flag=4;
}
}
else if(flag==4){
j--;
if(j<0||a[i][j]!=-1){
j++;
flag=1;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
// 加负号为左对齐,数字表示占三个字符不够用空格补齐,这样只打印一个空格就行
printf("%-3d ",a[i][j]);
}
printf("\n");
}
}

2.4日期类问题

根据日期算星期几(不考虑闰年)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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

int main()
{
int f[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
char str[8][10]={"Thursday","Friday","Saturday","Sunday","Monday","Tuesday","Wednesday"};
int month,day,ans=0;
cin>>month>>day;
ans+=day;
for(int i=4;i<month;i++){
ans+=f[i];
}
ans-=12;
printf("%s",str[ans%7]);
}

计算到1年1月1日的日期天数,再相减得到天数差

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

#include <stdio.h>

// 判断是否为闰年
int isLeapYear(int year) {
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return 1; // 是闰年
}
return 0; // 不是闰年
}

// 获取每个月的天数
int getDaysInMonth(int month, int year) {
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && isLeapYear(year)) {
return 29; // 闰年二月有29天
}
return days[month - 1];
}

// 计算从1年1月1日到指定日期的天数
int dateToDays(int year, int month, int day) {
int days = 0;
// 计算完整的年份部分的天数
for (int i = 1; i < year; i++) {
days += isLeapYear(i) ? 366 : 365;
}

// 计算当前年份已过的天数
for (int i = 1; i < month; i++) {
days += getDaysInMonth(i, year);
}

// 加上当前月份的天数
days += day;

return days;
}

// 计算两个日期之间的天数差
int daysBetweenDates(int year1, int month1, int day1, int year2, int month2, int day2) {
// 将两个日期分别转换为天数
int days1 = dateToDays(year1, month1, day1);
int days2 = dateToDays(year2, month2, day2);

// 返回它们之间的差值
return days2 - days1;
}

int main() {
int year1, month1, day1;
int year2, month2, day2;

// 输入两个日期
printf("请输入第一个日期 (yyyy mm dd):");
scanf("%d %d %d", &year1, &month1, &day1);

printf("请输入第二个日期 (yyyy mm dd):");
scanf("%d %d %d", &year2, &month2, &day2);

// 计算并输出两个日期之间的天数差
int diff = daysBetweenDates(year1, month1, day1, year2, month2, day2);
printf("两个日期之间的天数差为:%d天\n", diff);

return 0;
}

1410

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>

using namespace std;

bool isrun(int m)
{
if(m%100!=0&&m%4==0) return true;
if(m%400==0) return true;
return false;
}

int main ()
{
int year, days;
while(scanf("%d %d",&year,&days)!=EOF){
int f[]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(isrun(year)) f[1]=29;
int month=0;
// 核心逻辑:只有当剩余天数大于当月天数时,才进入下一个月
while(days>f[month]){
days-=f[month];
month++;
}
printf("%04d-%02d-%02d\n",year,month+1,days);
}
}

1446

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>

using namespace std;

bool isrun(int m)
{
if(m%100!=0&&m%4==0) return true;
if(m%400==0) return true;
return false;
}

int main ()
{
int n;
scanf("%d",&n);
while(n>0){
int y,m,d,t;
int f[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
scanf("%d %d %d %d",&y,&m,&d,&t);
if(isrun(y)) f[2]=29;
int days = d+t;
while(days>f[m]){
// 每次循环都重新判断当前年份的2月天数(处理跨年闰年)
if(isrun(y)) f[2]=29;
else f[2]=28;
days-=f[m];
m++;
// ========== 核心修改2:处理跨年 ==========
if(m > 12) {
y++;
m = 1;
}
}
printf("%04d-%02d-%02d\n",y,m,days);
n--;
}
}

1053

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

#include <bits/stdc++.h>

using namespace std;


int main ()
{
int n;
scanf("%d",&n);
while(n>0){
int hour,minu;
scanf("%d:%d",&hour,&minu);
int hhour,mminu;
hhour=hour+13;
mminu=minu+15;
//先处理分钟
if(mminu>=60){
//处理小时
hhour+=mminu/60;
mminu=mminu%60;
}
//处理天数
hhour=hhour%24;
printf("%d:%d\n",hhour,mminu);
n--;
}
}

2.5字符串问题

1012

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <bits/stdc++.h>

using namespace std;

int main ()
{
string a,a1,a2;
// scanf("%s",a);不能这样读取字符串
cin >> a;
for(int i=0;i<a.size();i++){
// 修正2:核心判断——是否为数字字符
if(a[i] >= '0' && a[i] <= '9'){
a2 += a[i]; // 数字字符放入a2
} else {
a1 += a[i]; // 非数字字符(字母、符号等)放入a1
}
}
// 修正3:输出string需用c_str(),或直接用cout
cout << a1 << a2 << endl;
// 若坚持用printf:printf("%s%s\n", a1.c_str(), a2.c_str());
}

1292

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>

using namespace std;


int main ()
{
string s;
//使用字符串时这样读取多组输入
while(getline(cin,s)){
int a[27]={0};
//对输入的字符串进行for遍历这样获取index
for(char c:s){
if(c>='A'&&c<='Z'){
int index=c-'A';
a[index]++;
}
}
for(int i=0;i<26;i++){
char c='A'+i;
printf("%c:%d\n",c,a[i]);
}
}
}

1240

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>

using namespace std;

int main ()
{
string s;
//cin读到空格会停止,getline不会
while (getline(cin, s)) {
int i=0;
for(char c:s){
//在这里还要判断下一个是否为小写,并且有无越界
if((s[i]==' '||s[i]=='\t'||s[i]=='\r'||s[i]=='\n') && (i+1 < s.size()) && (s[i+1]>='a'&&s[i+1]<='z'))
s[i+1]-=32;
i++;
}
if(s[0]>='a'&&s[0]<='z'){
s[0]-=32;
}
cout<<s<<endl;
}
}

1394

重点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>

using namespace std;

int main ()
{
string s;
while(getline(cin, s)){
bool first_kg=false;//防止出现多个空格的情况
int i=0;
bool first_word=true;//防止.前有空格输出0
for(char c:s){
if(c=='.'){
// 修正1:最后一个单词输出时,不再强制加空格,按first_word判断
if(first_kg){ // 确保是有效单词(避免.前有空格输出0)
if(!first_word) printf(" ");
printf("%d",i);
}
break;
}
if(c!=' '){
i++;
first_kg=true;// 标记“正在统计有效单词”
}
if(c==' '){
if(first_kg){ // first_kg=true(刚统计完hello),进入判断
if(!first_word) printf(" ") ;// first_word=true,不输出空格
printf("%d",i);
i=0;
first_kg=false;// 标记“离开单词,进入空格状态”
first_word=false;// 标记“已输出第一个单词,后续输出要加空格”
}
}
}
printf("\n");
}
}

1027

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>

using namespace std;

int main ()
{
string s,t;
getline(cin,s);
int i=0;
// 修正1:t初始为空,用+=追加字符(而非直接赋值t[i])
for(char c:s){
t+=tolower(c);
i++;
}
i=0;
for(char c:t){
if(i + 2 < t.size() && t[i]=='g'&&t[i+1]=='z'&&t[i+2]=='u'){
t[i]='0';
t[i+1]='0';
t[i+2]='0';
i+=3;
}
else
i++;
}
i=0;
for(char c:t){
if(c!='0'){
printf("%c",s[i]);
}
i++;
}
printf("\n");
}