省赛前的刷题训练(二)

省赛刷题训练(二)

Values whose Sum is 0

UVA 1152

一个简单的二分题目,将a数组和b数组排个序,c数组和d数组排个序,然后对第二个数组进行二分查找。这里要找的是个数,所以upper_bound和lower_bound一相减然后加起来就是答案。

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 <iostream>
#include <algorithm>
#include <stdio.h>
#include <string>
#include <queue>
#include <cstring>
using namespace std;
int e[4001 * 4001],f[4001 * 4001];
int a[4001],b[4001],c[4001],d[4001];
int main()
{
int t, n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0; i < n; ++i)
{
scanf("%d %d %d %d",&a[i],&b[i],&c[i],&d[i]);
}
int tot = 0;
for(int i = 0 ; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
e[tot++] = a[i] + b[j];
}
}
tot = 0;
for(int i = 0; i < n; ++i)
{
for(int j = 0 ;j < n; ++j)
{
f[tot++] = c[i] + d[j];
}
}
sort(e , e + tot);
sort(f , f + tot);
int sum = 0;
for(int i = 0; i < tot; ++i)
{
int m = upper_bound(f , f + tot , -e[i]) - lower_bound(f ,f + tot, -e[i]);
sum += m;
}
cout << sum << '\n';
if(t)
cout << '\n';
}
}

Humble numbers

HDU 1058

再一次做感觉思路清晰了挺多,第一次做没有理解本质,再一次做的时候,想到每一个数其实都可以通过它前面的数字乘积得到。2 3 5 7作为乘积的一个参数,另一个参数就是前面已经出现过的数字。比如8,通过2 * 4得到,2是一个因子,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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;
int a[10001];
int elect()
{
int aa = 1, bb = 1, cc = 1, dd = 1;
a[1] = 1;
for(int i = 2; i <= 5842; ++i)
{
a[i] = min(2 * a[aa], min(3 * a[bb], min(5 * a[cc] , 7 * a[dd])));
if(a[i] == 2 * a[aa])
aa++;
if(a[i] == 3 * a[bb])
bb++;
if(a[i] == 5 * a[cc])
cc++;
if(a[i] == 7 * a[dd])
dd++;
}
}
int main()
{
int n;
elect();
while(scanf("%d" ,&n) != EOF && n)
{
if(n % 10 == 1 && n % 100 != 11)
{
printf("The %dst humble number is %d.\n",n,a[n]);
}
else if(n % 10 == 2 && n % 100 != 12)
{
printf("The %dnd humble number is %d.\n",n,a[n]);
}
else if(n % 10 == 3 && n % 100 != 13)
{
printf("The %drd humble number is %d.\n",n,a[n]);
}
else{
printf("The %dth humble number is %d.\n",n,a[n]);
}
}
}

Train Problem I

HDU 1022

模拟火车的进出站。注意栈为空就要停止。

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 <bits/stdc++.h>
using namespace std;
struct node{
string s;
}b[1001];
int main()
{
int n;
while(cin >> n)
{
stack<char>S;
string s,s1;
cin >> s;
cin >> s1;
int tot = 0;
int ans = 0;
for(int i = 0; i < s.size(); ++i)
{
S.push(s[i]);
b[ans++].s = "in";
while(s1[tot] == S.top())
{
S.pop();
tot++;
b[ans++].s = "out";
if(tot == s1.size() || S.empty())
break;
}
}
if(S.size() == 0)
{
cout << "Yes." << '\n';
for(int i = 0; i < ans; ++i)
{
cout << b[i].s << '\n';
}
cout << "FINISH" << '\n';
}
else{
cout << "No." << '\n';
cout << "FINISH" << '\n';
}
}
}

Prime Friend

HDU 3823

需要注意的是输入的A和B的大小关系不一定,素数打表范围要开的很大。第一次WA是因为没有搞懂什么是prime neighbor . 比如说输入2 和 4这两个数字,我们找到了1,因为1 + 2 和 1 + 4是素数,同时 3 和 5 还是素数相邻。 这样的话我们最终在枚举的时候,就枚举相邻的两个素数就行了,满足条件的话就输出对应的数字。而不是从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
#include <bits/stdc++.h>
using namespace std;
const int maxn = 20000001;
bool is[maxn];
int tot;
int prime[maxn];
void Prime()
{
memset(is,0,sizeof(is));
is[0] = is[1] = 1;
tot = 0;
for(int i = 2; i < maxn; ++i)
{
if(!is[i])
{
prime[tot++] = i;
for(int j = i + i; j < maxn; j += i)
{
is[j] = 1;
}
}
}
}
int main()
{
Prime();
int t,caser = 1,A,B;
cin >> t;
while(t--)
{
scanf("%d %d",&A,&B);
if(A > B)
swap(A,B);
printf("Case %d: ",caser++);
int flag = -1;
for(int i = 0; i + 1 < tot; ++i)
{
if(prime[i + 1] - prime[i] == B - A && prime[i] >= A)
{
flag = prime[i] - A;
break;
}
}
cout << flag << '\n';
}
}