新手村
- 关卡1-1
小鱼游泳时间,它发现自己从a时b分一直游泳到当天的c时d分,请你帮小鱼计算一下,它这天一共游了多少时间呢?
一行内输入 4 个整数,分别表示 a, b, c, d
1
2
3
4
5
6
7
8
9
| #include <cstdio>
int main()
{
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
printf("%d %d", ((c - a) * 60 + d - b) / 60, ((c - a) * 60 + d - b) % 60);
//求几时几分的 算法;其他比如几元几角得换成同一单位再进行计算
return 0;
}
|
- 2-2 输入包括7 行数据,分别表示周一到周日的日程安排。每行包括两个小于10 的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。
输出一个数字。如果不会不高兴则输出0,如果会则输出最不高兴的是周几(用1, 2, 3, 4, 5, 6, 7 分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #include <cstdio>
int main()
{
int a[10], b[10], i, sum = 0, ans = 0;
for (i = 1; i <= 7; i++)
{
scanf("%d%d", &a[i], &b[i]);
a[i] = a[i] + b[i];
//这种方法比较巧妙,如果有两种不同类型的数据,也有对应关系,用两个数组来做,这题把第一个数组的值覆盖掉了,
//没多大坏处,而且还少定义了一个专门来存两个值的和的数组
}
for (i = 1; i <= 7; ++i)
{
if (a[i] > 8 && a[i] > sum)
{
ans = i; //ans是answer的简写
sum = a[i];
}
}
printf("%d\n", ans);
return 0;
}
|
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
| #include <iostream>
using namespace std;
int main()
{
int need,num,price,total,min;
int i;
cin>>need;
cin>>num>>price;
if(need%num==0) total=(need/num)*price;//需要数与包装数恰好相等时的价格
else total=(need/num)*price+price;//需要数与包装数不等时的价格
min=total;//第一种包装花费的钱数
//这个if用的很好,要找出来几种情况来分情况讨论
for(i=1;i<3;i++)//计算另外两种方案所需的价格
{
cin>>num>>price;
if(need%num==0) total=(need/num)*price;
else total=(need/num)*price+price;
if(min>total) min=total;//如果当前的花费比第一种小,令花费数等于当 前的钱数
}
cout<<min<<endl;
return 0;
}
|
将1,2,⋯,9共9个数分成3组,分别组成3个三位数,且使这3个三位数构成1:2:3的比例,试求出所有满足条件的33个三位数。
小技巧:分别得到每个数的个十百位,其中1 2 3 4 5 6 7 8 9 = 362880;1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45能判定数字是否重复
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 <stdio.h>
int main() {
int a, b, c;
int x[10];
int m, n, i;
for(a = 123; a <= 333; a++) {
b = a * 2;
c = a * 3;
x[1] = a % 10;
x[2] = a / 10 % 10;
x[3] = a / 100;
x[4] = b % 10;
x[5] = b / 10 % 10;
x[6] = b / 100;
x[7] = c % 10;
x[8] = c / 10 % 10;
x[9] = c / 100;
m = 1;
n = 0;
for(i = 1; i <= 9; i++)
m *= x[i];
for(i = 1; i <= 9; i++)
n += x[i];
if(m == 362880 && n == 45)
printf("%d %d %d\n", a, b, c);
}
}
|
一个很特别的for循环,原来for循环可以这么写
1
2
3
4
5
6
7
8
9
10
11
| #include <cstdio>
using namespace std;
int main()
{
int k, n = 0;
scanf("%d", &k);
for(double sum = 0; sum <= k; n++,sum += 1.0 / n);
//此时for循环要加 ;才可以
printf("%d", n);
return 0;
}
|
stdio.h是以往的C和C++的头文件,cstdio是标准C++(STL),且cstdio中的函数都是定义在一个名称空间std里面的,如果要调用这个名字空间的函数,必须得加std::或者在文件中声明using namespace std。
关卡3-4 小鱼的航程,这一题的for循环和if判断用的很好
有一只小鱼,它平日每天游泳 250 公里,周末休息(实行双休日),假设从周x(1≤x≤7) 开始算起,过了 n(n≤10^6 ) 天以后,小鱼一共累计游泳了多少公里呢?
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<cstdio>
int main()
{
unsigned long long n, ans=0;
int x;
scanf("%d%lld", &x, &n);
for(int i = 0; i < n; i++)
{
if((x != 6) && (x != 7))
{
ans += 250;
}
if(x == 7)
{
x = 1;
}
else
{
x++;
}
}
printf("%lld\n", ans);
return 0;
}
|
关卡 3-5
试计算在区间 1到 n 的所有整数中,数字x(0≤x≤9)共出现了多少次?例如,在 1到 11 中,即在 1,2,3,4,5,6,7,8,9,10,11 中,数字 1 出现了 4 次。
(考到了:优化,模拟,字符串,分离数位)有关各个位数的特点的可以用以下这种方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| #include <cstdio>
int main()
{
long long n, x, b, c, ans=0;
scanf("%lld%lld", &n, &x);
for (long long i = 1; i <= n; i++)
{
b = i;
while(b != 0)
{
c = b % 10;
b = b / 10;
if(c == x)
{
ans++;
}
}
}
printf("%lld\n", ans);
return 0;
}
|
- 关卡4-1
校门外的树,首先想到的是要把后面的值从前面中减去,可是这样不太可行,可以转换方法,让前面中的在后面出现的(即要减去的值)变为0,这种问题要改变一下原本数据的特征值。
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
| #include <cstdio>
using namespace std;
int a[105];
int b[105];
int f[10005];
int main()
{
int l, n;
int sum = 0;
scanf("%d%d", &L, &n);
for(int i = 1; i <= n; i++)
scanf("%d%d", &a[i], &b[i]);
for(int i = 0; i <= L; i++)
{
f[i] = 1; //让树都有一个特征值
}
for(int i = 1; i <= n; i++)
{
for(int j = a[i]; j <= b[i]; j++)
{
f[j] = 0; //若要减去这个值,可以把其特征值改变
}
}
for(int i = 0; i <= l; i++)
{
if(f[i] > 0) {
sum += 1;
}
}
printf("%d\n", sum);
return 0;
}
|
他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
| 方法0:就是把任意两个数的和求出来,与数组里的值比较一遍,这样子不行,应为有时候是数a和数a与另一个数的和比较,这种情况是不满足要求的
方法一:这种不行,因为不确定那两个数都在这一个数的前面
#include <cstdio>
#include <algorithm>
int a[101], s, n, vk[101];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n - 2; i++)
{
for(int j = i + 1; j <= n - 1; j++)
{
for(int k = j + 1; k <= n; k++)
{
if(a[i] + a[j] == a[k] && vk[k] == 0)
{
s++;
vk[k] = 1;
}
}
}
}
printf("%d\n", s);
return 0;
}
方法二:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, k, n, b, m;
int a[100];
scanf("%d", &n); //输入数据个数
for(i=0; i<n; i++) //循环输入正整数值
{
scanf("%d", &a[i]);
}
b = 0;
for(i=0; i<n-1; i++) //循环把数组中整数排序,冒泡排序
{
for(j=i+1; j<n; j++)
{
if(a[i] > a[j])
{
b = a[i];
a[i] = a[j];
a[j] = b;
}
}
}
m = 0;
/*a[i]中数据以排序,故两个数之和等于a[i]的两个数必在第i个数a[i]之前
把a[i]第二个数之前的数据逐个相加直到符合条件*/
for(i=2; i<n; i++) //一层循环,从第2个数据开始遍历a[i]
{
for(j=0; j<i-1; j++) //二层循环,控制j从第0个数据开始到i-1遍历a[i]
{
for(k=j+1; k<i; k++) //三层循环,从k=j+1开始遍历到i
{
if(a[j]+a[k] == a[i]) //比较如果i前有两个不同数据之和等于a[i]则m+1
{
m++;
goto skip; //如果有一个符合条件的就用goto跳出多重循环,不用再比较其余的啦,这算是优化
}
}
}
skip: ;
}
printf("%d\n", m);
return 0;
}
方法四:
#include <iostream>
using namespace std;
int main(){
int a[110]={0},b[110]={0};
int n,count=0;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
b[i]=a[i];
}
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
int t=a[i]+a[j];
for(int p=0;p<n;p++){
if(b[p]==t && p!=i && p!=j){
count++;
b[p]=0;
}
}
}
}
cout<<count;
return 0;
}
|
*关卡4-4
可爱鱼的数目,即在本条鱼的前面,有多少个不如自己可爱的鱼的数目
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 <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, n;
int a[100], b[100]={0}; //此时数组b一定都要初始化为0,不然没有改变数组的值的数组值是不确定的数
scanf("%d", &n);
for(i=0; i<n; i++) //循环输入鱼的可爱数值
{
scanf("%d", &a[i]);
}
int k;
for(i=0; i<n; i++) //第一层循环,控制i,第i个数据和前面的i-1个数据比较
{
for(j=0; j<i; j++) //第二层循环,控制j,控制前i-1个数据和第i比较
{
if(a[i] > a[j]) //第i个和前i-1个数据比较
{
b[i]++;
}
}
}
for(i=0; i<n; i++) //循环输出
{
printf("%d ", b[i]);
}
return 0;
}
|
- 关卡4-5
输入格式:
第 1 行:一个整数 N 。1 ~ 10^6
第 2 行:N个空格隔开的整数,表示连续 N 天的最高气温。
输出格式:
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
67
68
69
70
| 方法一:
#include <bits/stdc++.h>
using namespace std;
int a[10000002];
int n, sum = 1, ans;
int main()
{
scanf("%d", &n);
a[n + 1] = -1;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for(int i = 2; i <= n + 1; i++)
{
if(a[i] < a[i - 1])
{
ans = max(sum, ans);
sum = 1;
}
else
{
sum++;
}
}
printf("%d\n", ans);
return 0;
}
方法二:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, N, n, m;
int temp[10000002]; //数组要开足够大,不然(..>^^>..)
scanf("%d", &N);
for (i = 0; i < N; i++)
{
scanf("%d", &temp[i]);
}
n = 1;
m = 0;
/*有两种输入情况:一、输入连续型数据 (1 2 3 4 5 6){不过这种情况与题目无关...}
二、输入非连续型 (1 2 3 2 4 5 6)*/
for (i = 0; i < N-1; i++) //循环遍历
{
if (temp[i] < temp[i+1]) //如果温度在持续上升,则n++计数
{
n++; //统计连续气温上升天数
/*对待第一种情况输入数据(1 2 3 4 5 6)做的判断*/
if (n > m) //比较当前最高气温连续天数和历史气温连续天数,如果前者大则将n赋值给m
{
m = n;
}
}
else //如果降温了(连续升温被打断了)
{
/*对待第二种情况输入数据(1 2 3 2 4 5 6)做的判断*/
if (n > m) //比较当前最高气温连续天数和历史气温连续天数,如果前者大则将n赋值给m
{
m = n;
}
n = 1; //计数器n清零
}
}
printf("%d", m);
return 0;
}
|
long与int:标准只规定long不小于int的长度,int不小于short的长度。
unsigned int (unsigned long)
4字节8位可表达位数:2^32=42 9496 7296
范围:0 ~ 42 9496 7295 (42*10^8)
int (long)
4字节8位可表达位数:2^32=42 9496 7296
范围:-21 4748 3648 ~ 21 4748 3647 (21*10^8)
long long (__int64)
8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
范围:-922 3372 0368 5477 5808 ~ 922 3372 0368 5477 5807 (922*10^16)
unsigned long (unsigned __int64)
8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
范围:0 ~ 1844 6744 0737 0955 1615 (1844*10^16)
1 判断 ISBN书号是否正确
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #include<cstdio>
char a[14], b[14], t1, t2;
int t22 = 0;
int main()
{
scanf("%c-%c%c%c-%c%c%c%c%c-%c", &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9], &t1);
for(int i = 1; i <= 9; ++i)
t2 += (a[i] - '0') * i; //字母变成数字的方法
t2 = t2 % 11 + '0';
if(t2 == '0' + 10) //数字变成字母的方法
t2 = 'X';
if(t1 == t2)
{
printf("Right");
return 0;
}
printf("%c-%c%c%c-%c%c%c%c%c-%c\n", a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], t2);
return 0;
}
|
- 判断是否上UFO
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
| #include <cstdio>
int main()
{
char a[7] = "", b[7] = "";
scanf("%[A-Z]\n%[A-Z]", &a, &b);
int c = 1, d = 1, i = 0;
while(a[i] != '\0')
{
c = c * (a[i] - 'A' + 1);
i++;
}
c = c % 47;
i = 0;
while(b[i]!='\0')
{
d = d * (b[i] - 'A' + 1); //这地方用的好,注意-'A'之后 要加1
i++;
}
//其中还有一个方法来判断
/*
scanf("%s",a); len=strlen(a);
for(int i=0;i<len;i++){ d*=(a[i]-64); d=d%47; }
*/
d = d % 47;
if (c == d) printf("GO");
else printf("STAY");
return 0;
}
|
3 栅栏密码
1
2
3
4
5
6
7
8
9
10
11
| #include <cstdio>
int main()
{
int n, i;
char a[50];
scanf("%d%s", &n, a);
for(i = 0; a[i] != '\0'; i++)
a[i] = 'a' + (a[i] - 'a' + n) % 26;
//提供了一种方法,先把字母变成相应数字,然后加上对应的变化值,然后 对26取余,在加上'a'就能求出该字母
puts(a);
}
|
4 查找字符串a是否包含子串b,不是用strA.find(strB) > 0 而是 strA.find(strB) != string:npos,其中string:npos是个特殊值,说明查找没有匹配;
int idx = str.find(“abc”);
if (idx == string::npos)
比较式 idx == string::npos 中,如果 idx 的值为-1,由于 idx 和字符串string::npos 型别不同,比较结果可能得到 false。
if(str.find(“abc”) ) ( 这样写也是错误的,找不到abc会返回-1,不为0为True。0为False )
通常来说,find函数用于寻找某个序列的在string中第一次出现的位置。
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int counter=0,begin=-1,pos=-1;
string s1,s2;
getline(cin,s1); //整行输入 ,可以把cin流放进去
getline(cin,s2);
for(int i=0;i<s1.size();i++)
s1[i]=toupper(s1[i]); 或者都变成小写字母用tolower方法
for(int i=0;i<s2.size();i++)
s2[i]=toupper(s2[i]);
s1=' '+s1+' ';
s2=' '+s2+' '; //这一步很重要,因为测试点有那种,比如给定单词的前面是空格,不加这个就判断不出来
while((begin=s2.find(s1,begin+1))!=string::npos){
counter++;
if(counter==1)
pos=begin;
}
if(pos!=-1)
cout<<counter<<" "<<pos;
else
cout<<pos;
return 0;
}
其中本题还可以用以下方法来获取字符串a中的单词
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;
const int maxn = 200000+10;
string b[maxn];
int main()
{
string s;
getline(cin,s);
stringstream ss;
ss<<s; //此时ss中就是由空格分开的 字符串 数组
int k=0;
while(ss)
{
ss>>b[k++];
}
for(int i=0;i<k;i++)
cout<<b[i]<<"\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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| #include<bits/stdc++.h>
using namespace std;
int spc[666666];
map<string,int>mp;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string a,c;
cin>>a;
cin.get();
for(int i=0;i<a.size();i++)
a[i]=tolower(a[i]);
string b;
getline(cin,b);
for(int i=0;i<b.size();i++)
if(isalpha(b[i]))
b[i]=tolower(b[i]);
stringstream s;
s<<b;
int ans;
int sum=0;
int k=0;
int f=1;
for(int i=0;i<b.size();i++)
if(isspace(b[i]))
spc[k]++,f=1;
else if(isalpha(b[i])&&f)
k++,f=0;
sum=spc[0];
f=1;
int w=0;
int cnt=1;
while(s>>c)
{
if(a==c&&f)
{
f=0;
w=sum;
}
mp[c]++;
sum+=c.size()+spc[cnt++];
}
if(mp[a])
cout<<mp[a]<<" "<<w;
else
cout<<-1;
}
|
5.
输入格式:四行字符,由大写字母组成,每行不超过100个字符
输出格式:由若干行组成,前几行由空格和星号组成,最后一行则是由空格和字母组成的。在任何一行末尾不要打印不需要的多余空格。不要打印任何空行。
* *
* * * *
* * * *
* * * * * *
* * * * * * * * *
* * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * *
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
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
|
#include<iostream>
#include<cstring>
#include<algorithm>//这个头文件中有max ,min这样的函数
using namespace std;
int main(){
string s;
char s1[800],s2[800],s3[800],s4[800],f;
int sum[30],length=0,maxnum=0;
cin.getline(s1,800);
cin.getline(s2,800);
cin.getline(s3,800);
cin.getline(s4,800);
int counter,begin=-1;
strcat(s1,s2);
//strcat 字符串拼接函数;
//char *strcpy(char *dest, const char *src)把 src 所指向的字符串复制到 dest;
//int strcmp(const char *str1, const char *str2) 如果返回值 > 0,则表示 str2 小于 str1。如果返回值 < 0,则表示 str1 小于 str2。如果返回值 = 0,则表示 str1 等于 str2。
strcat(s1,s3); //在s1的后面拼接s3字符串
strcat(s1,s4);
s.assign(s1);//字符数组转化字符串,string转化char[],strcpy(ch,str.c_str())
for(char x='A';x<='Z';x++){
counter=0;
while((begin=s.find(x,begin+1))!=string::npos){
counter++;
}
sum[length++]=counter;
}
for(int i=0;i<length;i++)
maxnum=max(maxnum,sum[i]);
for(int i=maxnum;i>0;i--){
for(int j=0;j<26;j++){
if(sum[j]>=i)
cout<<"*";
else
cout<<" ";
if(j!=25)
cout<<" ";
}
cout<<endl;
}
for(char x='A';x<='Z';x++)
cout<<x<<" ";
return 0;
}
|
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
|
#include<stdio.h>
int main()
{
int a[12],i;
int b,d,c,e=0;
double f;
for(i=0;i<12;i++){
scanf("%d",&a[i]);
}
for(i=0;i<12;i++){
b=-a[i]+300+e;
if(b>=100){
c=b/100;
f+=c*100;
b=b-c*100;
}
e=b;
if(b<0){
printf("-%d\n",i+1);
break;
}
}
if(i==12){
//d=;
printf("%d\n",(int)((f*12+b*10)/10));
}
}
/*
printf("%d\n",(int)((f*12+b*10)/10));
这样写就可以了, ((f*12+b*10)/10)这个数的结果是一个double类型,
因为int和double类型的相遇,会自动专向更高级的double类型
要是double类型用格式化%d输出,结果就为0
相应的也可以这样写printf("%.0lf\n",((f*12+b*10)/10));
那个double类型的数乘以一个小数,因为乘不尽,在内存中会
截取有效长度,所以会少1,题目给的答案就是通过乘一个整数,再除
一个整数来计算一个数乘以一个小数
重要,重要另一个问题是如果,double sum=0;int n=2; sum+=1/n;这样的sum值为1,而sum+=1.0/n;则sum为0.5;
*/
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| C语言有以下几种取整方法:
1、直接赋值给整数变量。如:
int i = 2.5; 或 i = (int) 2.5;
这种方法采用的是舍去小数部分
2、C/C++中的整数除法运算符“/”本身就有取整功能(int / int),但是整数除法对负数的取整结果和使用的C编译器有关。
3、floor函数。floor(x)返回的是小于或等于x的最大整数。如:
floor(2.5) = 2
floor(-2.5) = -3
4、使用ceil函数。ceil(x)返回的是大于x的最小整数。如:
ceil(2.5) = 3
ceil(-2.5) = -2
floor()是向负无穷大舍入,floor(-2.5) = -3;ceil()是向正无穷大舍入,ceil(-2.5) = -2。
floor()和ceil()函数在math.h头文件中定义
|