A 时间统计
题目描述
某个实验需要统计时间,记录了实验开始和结束的时间,计算实验用了多少秒。
输入描述:
第一行输入一个整数n,表示样例个数。接下来每组样例两行,表示开始时间和结束时间,格式为xdayHH:MM:SS,x是一个整数表示第几天,0 < x < 20000,HH表示小时,MM表示分钟,SS表示秒,保证时间合法,结束时间比开始时间晚。
输出描述:
每组数据输出一行一个整数,表示经过的秒数。
示例1
输入
2
1day03:26:12
1day04:26:12
123day15:00:01
19999day15:00:00
输出
3600
1717286399
简单题
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4
5 int main() {
6 int t;
7 cin >> t;
8 while(t--) {
9 ll d1, d2, h1, h2, m1, m2, s1, s2;
10 scanf("%lldday%lld:%lld:%lld",&d1,&h1,&m1,&s1);
11 scanf("%lldday%lld:%lld:%lld",&d2,&h2,&m2,&s2);
12 printf("%lld\n",(s2-s1)+(m2-m1)*60+(h2-h1)*3600+(d2-d1)*86400);
13 }
14 return 0;
15 }
B String
题目描述
有一个只包含大写字母和数字的字符串S,和一个6*6的字符组成的正方形如下图,正方形中恰好包含0-9和A-Z各一个字符。正方形的一行在字符串S中的出现次数是这行6个字符在S中出现次数的总和,正方形的一列在字符串S中的出现次数是这列6个字符在S中出现次数的总和。如果正方形中一个字符所在行的出现次数是所有行中最多,并且所在列的出现次数是所有列中最多,这个字符是需要被找出的。
012345
6789AB
CDEFGH
IJKLMN
OPQRST
UVWXYZ
输入描述:
第一行是一个整数T(1 ≤ T ≤ 400),表示样例的个数。
每个样例一行字符串S,长度1≤ len ≤ 500。
输出描述:
每组数据输出一行需要找出的所有字符,如果需要找出的字符有多个,所在行不同的按行从小到大排序,所在行相同的按列从小到大排序。
示例1
输入
3
13579
AADD
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
输出
13
7ADG
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
简单模拟题
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 char str[10][10] = {"012345","6789AB","CDEFGH",
5 "IJKLMN","OPQRST","UVWXYZ"};
6 char str1[550];
7 int ans1[10],ans2[10];
8 int main() {
9 int t;
10 cin >> t;
11 while(t--) {
12 cin >> str1;
13 int MAX = 0;
14 for(int i = 0; str1[i]; i ++) {
15 for(int j = 0; j < 6; j ++) {
16 for(int k = 0; k < 6; k ++) {
17 if(str[j][k] == str1[i]) {
18 ans1[j]++;
19 ans2[k]++;
20 }
21 }
22 }
23 }
24 for(int i = 0; i < 6; i ++) {
25 for(int j = 0; j < 6; j ++) {
26 MAX = max(MAX,ans1[i]+ans2[j]);
27 }
28 }
29 for(int i = 0; i < 6; i ++) {
30 for(int j = 0; j < 6; j ++) {
31 if(ans1[i]+ans2[j] == MAX)
32 cout << str[i][j];
33 }
34 }
35 cout << endl;
36 memset(ans1,0,sizeof(ans1));
37 memset(ans2,0,sizeof(ans2));
38 memset(str1,0,sizeof(str1));
39 }
40 return 0;
41 }
C Boom
题目描述
紧急事件!战场内被敌军埋放了n枚炸弹!
我军情报部门通过技术手段,掌握了这些炸弹的信息。这些炸弹很特殊,每枚炸弹的波及区域是一个矩形。第i枚炸弹的波及区域是以点(x i1,y i1)为左下角,点(x i2,y i2)为右上角的矩形。
mostshy,作为我军的指挥官,想要知道,如果这些弹同时被敌军引爆,最多将有多少枚炸弹会波及到同一个区域(不考虑边界和角落)。
我军情报部门通过技术手段,掌握了这些炸弹的信息。这些炸弹很特殊,每枚炸弹的波及区域是一个矩形。第i枚炸弹的波及区域是以点(x i1,y i1)为左下角,点(x i2,y i2)为右上角的矩形。
mostshy,作为我军的指挥官,想要知道,如果这些弹同时被敌军引爆,最多将有多少枚炸弹会波及到同一个区域(不考虑边界和角落)。
输入描述:
第一行是一个整数T(1 ≤ T ≤ 50),表示样例的个数。
以后每个样例第一行是一个整数n(1 ≤ n ≤ 50),表示炸弹的个数。
接下来n行,每行四个整数,第i行为x
i1,y
i1,x
i2,y
i2(0 ≤ x
i1,y
i1,x
i2,y
i2≤ 100),输入保证合法。
输出描述:
每个样例输出一行,一个整数,表示最多将有多少枚炸弹会波及到同一个区域。
示例1
输入
1
2
0 0 50 50
40 40 100 100
输出
2
说明
在左下角为(40,40),右上角为(50,50)的矩形区域内,有两个炸弹同时波及,所以答案为2。
有个坑,不能等于右上角点。
1 #include <bits/stdc++.h>
2 using namespace std;
3 int ans[110][110];
4 int main() {
5 int t, n;
6 cin >> t;
7 while (t--) {
8 cin >> n;
9 int MAX = 0;
10 while(n--) {
11 int a,b,c,d;
12 cin >> a >> b >> c >> d;
13 for(int i = a; i < c; i ++) {
14 for(int j = b; j < d; j ++) {
15 ans[i][j] ++;
16 MAX = max(MAX,ans[i][j]);
17 }
18 }
19 }
20 cout << MAX << endl;
21 memset(ans, 0, sizeof(ans));
22 }
23 return 0;
24 }
D Fibonacci进制
题目描述
Fibonacci数是非常有名的一个数列,它的公式为 f(n)=f(n-1)+f(n-2),f(0)=1,f(1)=2。
我们可以把任意一个数x表示成若干不相同的Fibonacci数的和, 比如说14 = 13+1 = 8+5+1 = 8+3+2+1。
如果把Fibonacci数列作为数的位权,即f(i)作为第i位的位权,每位的系数只能是0或者1,从而得到一个01串。 比如14可以表示成 100001,11001,10111。 我们再把这个01串看成2进制,再转成10进制以后就变成了 33,25,23。 为了避免歧义,我们将使用最小的那个值23。
请按照这个过程计算一下10进制整数通过上述转换过程得到的10进制整数。
输入描述:
第一行是一个整数T(1 ≤ T ≤ 10000),表示样例的个数。
以后每行一个样例,为一个十进制正整数x(1 ≤ x ≤ 109)。
输出描述:
每行输出一个样例的结果。
示例1
输入
5
1
10
100
1000
1000000000
输出
1
14
367
10966
4083305275263
任何数都可以用斐波拉系数表示,先找到一组可以用斐波拉系数表示的,由于f[i] = f[i-1] + f[i-2] 所以,如果用了第i个斐波拉系数没i-1 i-2没有用,那就换成后者
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N = 110;
5 ll f[N], x;
6 bool vis[N];
7 map<ll,int> mp;
8 void dfs(int id) {
9 if(id < 2) return ;
10 if(!vis[id-1] && !vis[id-2]) {
11 vis[id-1] = vis[id-2] = true;
12 vis[id] = false;
13 dfs(id-2);
14 }
15 }
16 int main() {
17 f[0] = 1;f[1] = 2;//43 1134903170
18 mp[1] = 0; mp[2] = 1;
19 for(int i = 2; i <55; i ++) {
20 f[i] = f[i-1] + f[i-2];
21 mp[f[i]] = i;
22 }
23 int t;
24 cin >> t;
25 while(t--) {
26 memset(vis, 0, sizeof(vis));
27 cin >> x;
28 while(x) {
29 if(mp[x] || x == 1) {
30 vis[mp[x]] = 1;
31 x = 0;
32 break;
33 }
34 int id = upper_bound(f,f+50,x/2)-f;
35 vis[id] = 1;
36 x -= f[id];
37 }
38 for(int i = 2; i < N; i ++) {
39 if(vis[i]) dfs(i);
40 }
41 for(int i = 0; i < 50; i ++) {
42 if(vis[i]) {
43 x += (1LL<<i);
44 }
45 }
46 cout << x << endl;
47 }
48 return 0;
49 }
E 吃货
题目描述
作为一个标准的吃货,mostshy又打算去联建商业街觅食了。
混迹于商业街已久,mostshy已经知道了商业街的所有美食与其价格,而且他给每种美食都赋予了一个美味度,美味度越高表示他越喜爱这种美食。
mostshy想知道,假如带t元去商业街,只能吃一种食物,能够品味到的美食的美味度最高是多少?
混迹于商业街已久,mostshy已经知道了商业街的所有美食与其价格,而且他给每种美食都赋予了一个美味度,美味度越高表示他越喜爱这种美食。
mostshy想知道,假如带t元去商业街,只能吃一种食物,能够品味到的美食的美味度最高是多少?
输入描述:
第一行是一个整数T(1 ≤ T ≤ 10),表示样例的个数。
以后每个样例第一行是两个整数n,m(1 ≤ n,m ≤ 30000),表示美食的种类数与查询的次数。
接下来n行,每行两个整数分别表示第i种美食的价格与美味度di,ci(1 ≤ di,ci ≤ 109)。
接下来m行,每行一个整数表示mostshy带t(1 ≤ t ≤ 1e9)元去商业街觅食。
输出描述:
每个查询输出一行,一个整数,表示带t元去商业街能够品味到美食的最高美味度是多少,如果不存在这样的美食,输出0。
示例1
输入
1
3 3
1 100
10 1000
1000000000 1001
9
10
1000000000
输出
100
1000
1001
说明
大量的输入输出,请使用C风格的输入输出。
当10元可以得到1000,而100元得到100时,换成100得到1000,这样在用二分查找最接近t元可以获得多少美味值就行
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N = 30010;
5 struct Nod{
6 int d, c;
7 }nod[N];
8 int MAX[N];
9 bool cmp(Nod &a, Nod &b) {
10 if(a.d != b.d) return a.d < b.d;
11 else return a.c > b.c;
12 }
13 int main() {
14 int t;
15 scanf("%d",&t);
16 while(t--) {
17 int n, m;
18 scanf("%d%d",&n,&m);
19 for(int i = 1; i <= n; i ++) cin >> nod[i].d >> nod[i].c;
20 sort(nod+1,nod+1+n,cmp);
21 for(int i = 1; i <= n; i ++) {
22 MAX[i] = max(MAX[i-1],nod[i].c);
23 // cout << MAX[i] << ' ' ;
24 }
25 // cout <<endl;
26 while(m--) {
27 int x, ans = 0;
28 scanf("%d",&x);
29 int l = 1, r = n;
30 while(l <= r) {
31 int m = (l+r)>>1;
32 if(x >= nod[m].d) {
33 ans = MAX[m];
34 l = m+1;
35 } else r = m-1;
36 }
37 printf("%d\n",ans);
38 // cout << ans << endl;
39 }
40 }
41 return 0;
42 }
F maze
题目描述
小明来到一个由n x m个格子组成的迷宫,有些格子是陷阱,用'#'表示,小明进入陷阱就会死亡,'.'表示没有陷阱。小明所在的位置用'S'表示,目的地用'T'表示。
小明只能向上下左右相邻的格子移动,每移动一次花费1秒。
有q个单向传送阵,每个传送阵各有一个入口和一个出口,入口和出口都在迷宫的格子里,当走到或被传送到一个有传送阵入口的格子时,小明可以选择是否开启传送阵。如果开启传送阵,小明就会被传送到出口对应的格子里,这个过程会花费3秒;如果不开启传送阵,将不会发生任何事情,小明可以继续向上下左右四个方向移动。
输入描述:
有多组数据。对于每组数据:
第一行有三个整数n,m,q(2≤ n,m≤300,0≤ q ≤ 1000)。
接下来是一个n行m列的矩阵,表示迷宫。
最后q行,每行四个整数x1,y1,x2,y2(0≤ x1,x2< n,0≤ y1,y2< m),表示一个传送阵的入口在x1行y1列,出口在x2行y2列。
输出描述:
如果小明能够活着到达目的地,则输出最短时间,否则输出-1。
示例1
输入
5 5 1
..S..
.....
.###.
.....
..T..
1 2 3 3
5 5 1
..S..
.....
.###.
.....
..T..
3 3 1 2
5 5 1
S.#..
..#..
###..
.....
....T
0 1 0 2
4 4 2
S#.T
.#.#
.#.#
.#.#
0 0 0 3
2 0 2 2
输出
6
8
-1
3
bfs问题,多了传送,用二维数组存储传送位置,先上下左右,在用传送,取最小值。
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 const int N = 330;
5 char str[N][N];
6 typedef pair<int,int> P;
7 std::vector<P> v[N][N];
8 int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
9 int sx, sy, tx, ty, n, m, q;
10 int d[N][N];
11 void bfs() {
12 queue<P> que;
13 memset(d, -1, sizeof(d));
14 que.push(P(sx,sy));
15 d[sx][sy] = 0;
16 while(que.size()) {
17 P p = que.front(); que.pop();
18 for(int i = 0; i < 4; i ++) {
19 int nx = dx[i] + p.first, ny = dy[i] + p.second;
20 if(0 <= nx && nx < n && 0 <= ny && ny < m && str[nx][ny] != '#') {
21 if(d[nx][ny] == -1 || d[nx][ny] > d[p.first][p.second] + 1) {
22 que.push(P(nx,ny));
23 d[nx][ny] = d[p.first][p.second] + 1;
24 }
25 }
26 }
27 for(int i = 0; i < v[p.first][p.second].size(); i ++) {
28 int nx = v[p.first][p.second][i].first;
29 int ny = v[p.first][p.second][i].second;
30 if(0 <= nx && nx < n && 0 <= ny && ny < m && str[nx][ny] != '#') {
31 if(d[nx][ny] == -1 || d[nx][ny] > d[p.first][p.second] + 1) {
32 que.push(P(nx,ny));
33 d[nx][ny] = d[p.first][p.second] + 3;
34 }
35 }
36 }
37 }
38 }
39 void init() {
40 memset(str,0,sizeof(str));
41 for(int i = 0; i < N; i ++) {
42 for(int j = 0; j < N; j ++) {
43 v[i][j].clear();
44 }
45 }
46 }
47 int main() {
48 while(cin >> n >> m >> q) {
49 for(int i = 0; i < n; i ++) cin >> str[i];
50 for(int i = 1; i <= q; i ++) {
51 int x1, x2, y1, y2;
52 cin >> x1 >> y1 >> x2 >> y2;
53 v[x1][y1].push_back(P(x2,y2));
54 }
55 for(int i = 0; i < n; i ++) {
56 for(int j = 0; j < m; j ++) {
57 if(str[i][j] == 'S') {
58 sx = i;sy = j;
59 }else if(str[i][j] == 'T') {
60 tx = i; ty = j;
61 }
62 }
63 }
64 bfs();
65 printf("%d\n",d[tx][ty]);
66 init();
67 }
68 return 0;
69 }
G又见斐波那契
H 统计颜色
题目描述
n个桶按顺序排列,我们用1~n给桶标号。有两种操作:
1 l r c 区间[l,r]中的每个桶中都放入一个颜色为c的球 (1≤l,r ≤n,l≤r,0≤c≤60)
2 l r 查询区间[l,r]的桶中有多少种不同颜色的球 (1≤l,r ≤n,l≤r)
1 l r c 区间[l,r]中的每个桶中都放入一个颜色为c的球 (1≤l,r ≤n,l≤r,0≤c≤60)
2 l r 查询区间[l,r]的桶中有多少种不同颜色的球 (1≤l,r ≤n,l≤r)
输入描述:
有多组数据,对于每组数据:
第一行有两个整数n,m(1≤n,m≤100000)
接下来m行,代表m个操作,格式如题目所示。
输出描述:
对于每个2号操作,输出一个整数,表示查询的结果。
示例1
输入
10 10
1 1 2 0
1 3 4 1
2 1 4
1 5 6 2
2 1 6
1 7 8 1
2 3 8
1 8 10 3
2 1 10
2 3 8
输出
2
3
2
4
3
大佬的思路,很巧妙。由于颜色只要60,用数组变成某个颜色的区间,然后查询就可以了。
1 #include <bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4
5 struct Nod{
6 vector<int> l, r;
7 }nod[66];
8
9 int main() {
10 int n, m;
11 while(scanf("%d%d",&n,&m) != EOF) {
12 for(int i = 0; i <= 60; i ++) {
13 nod[i].l.clear();
14 nod[i].r.clear();
15 }
16 int op, l, r , c;
17 while(m--) {
18 scanf("%d", &op);
19 if(op == 1) {
20 scanf("%d%d%d",&l,&r,&c);
21 nod[c].l.push_back(l);
22 nod[c].r.push_back(r);
23 } else {
24 scanf("%d%d",&l,&r);
25 int ans = 0;
26 for(int i = 0; i <= 60; i ++) {
27 for(int j = 0; j < nod[i].l.size(); j ++) {
28 if(nod[i].l[j] <= r && nod[i].r[j] >= l) {
29 ans++;
30 break;
31 }
32 }
33 }
34 cout << ans << endl;
35 }
36 }
37 }
38 return 0;
39 }
来源:oschina
链接:https://my.oschina.net/u/4311560/blog/3992320